我正在使用来自migrate2rocky.sh的GitHub脚本进行测试:
https://github.com/rocky-linux/rocky-tools/blob/main/migrate2rocky/migrate2rocky.sh
我昨天测试了这个,效果很好。今天,我又回到了一张快照中,再做一次。这一次,脚本在第一次检查时失败:
if [ -n "$POSIXLY_CORRECT" ] || [ -z "$BASH_VERSION" ]; then
printf '%s\n' "bash >= 4.0 is required for this script." >&2
exit 1
fi具体来说,它在$POSIXLY_CORRECT测试中失败(我独立运行了代码片段以验证). I检查了运行的bash版本:
[user@server ~]$ rpm -qa | grep bash
bash-completion-2.7-5.el8.noarch
bash-4.4.20-1.el8_4.x86_64
[user@server ~]$ echo $BASH_VERSION
4.4.20(1)-release
[user@server ~]$ echo $POSIXLY_CORRECT
[user@server ~]$据我所知,POSIX是一个标准集,可以简化类似UNIX的OSs之间的应用程序可移植性。
在我们的服务器上没有进行任何更改来解释为什么脚本不再工作。我在尚未使用脚本的服务器上测试了脚本,并出现了同样的问题。
服务器都是CentOS 8.4。
我不知道$POSIXLY_CORRECT是做什么的,也不知道昨天天气好的时候为什么会出错。
如果你有任何疑问,请告诉我,我真的迷路了。
sudo bash -x migrate2rocky.sh命令的输出:
[user@server ~]$ sudo bash -x migrate2rocky.sh
+ '[' -n '' ']'
+ '[' -z '4.4.20(1)-release' ']'
+ (( BASH_VERSINFO < 4 ))
+ (( EUID != 0 ))
+ logfile=/var/log/migrate2rocky.log
+ truncate -s0 /var/log/migrate2rocky.log
+ exec
++ tee -a /var/log/migrate2rocky.log
++ tee -a /var/log/migrate2rocky.log
+ errcolor=
+ blue=
+ nocolor=
+ export LANG=en_US.UTF-8
+ LANG=en_US.UTF-8
+ shopt -s nullglob
+ SUPPORTED_MAJOR=8
+ SUPPORTED_PLATFORM=platform:el8
++ arch
+ ARCH=x86_64
+ gpg_key_url=https://dl.rockylinux.org/pub/rocky/RPM-GPG-KEY-rockyofficial
+ gpg_key_sha512=88fe66cf0a68648c2371120d56eb509835266d9efdf7c8b9ac8fc101bdf1f0e0197030d3ea65f4b5be89dc9d1ef08581adb068815c88d7b1dc40aa1c32990f6a
+ declare -A repo_urls
+ repo_urls=([rockybaseos]="https://dl.rockylinux.org/pub/rocky/${SUPPORTED_MAJOR}/BaseOS/$ARCH/os/" [rockyappstream]="https://dl.rockylinux.org/pub/rocky/${SUPPORTED_MAJOR}/AppStream/$ARCH/os/")
+ unset CDPATH
+ convert_info_dir=/root/convert
+ unset convert_to_rocky reinstall_all_rpms verify_all_rpms update_efi
+ noopts=0
+ getopts hrVR option
+ (( ! noopts ))
+ usage
+ printf '%s\n' 'Usage: migrate2rocky.sh [OPTIONS]' '' Options: '-h Display this help' '-r Convert to rocky' '-V Verify switch' ' !! USE WITH CAUTION !!'
Usage: migrate2rocky.sh [OPTIONS]
Options:
-h Display this help
-r Convert to rocky
-V Verify switch
!! USE WITH CAUTION !!
+ exit 1
[user@server ~]$奇怪的是,正如您在上面看到的那样,当通过“POSIXLY_CORRECT”命令而不是"sh“运行时,命令可以正常工作(它通过更高级的bash测试,然后继续测试BASH_VERSION和EUID的值),就像我昨天做的那样。
发布于 2021-06-15 14:17:11
错误消息表明,您没有使用比版本4.0更新的bash外壳版本来运行它。据推测,该脚本依赖于bash shell实现的特性,这些特性不同于或扩展了用于Unix语言的POSIX标准所规定的特性集。
问题的结尾证实了您使用sh运行它,在您的系统中,这可能是一些bash以外的shell。即使您的sh是伪装的bash,它也是以POSIX模式运行的shell。
考虑使用bash运行脚本,或者,如果脚本顶部有一个#!-line,只需使脚本可执行(使用chmod +x scriptname),然后像./scriptname一样运行它。
POSIXLY_CORRECT环境变量是一个变量,当工具实现与POSIX标准所规定的行为不同的行为时,它帮助实用程序选择行为。
在POSIX模式下,bash外壳的工作方式略有不同(即,如果启用了set -o posix,或者以sh的形式启动了shell )。这些差异在bash手册中题为“D15”的部分中进行了描述。
发布于 2021-06-20 16:25:07
用一些上下文的细节来补充克莎拉南达的回答。
在链接Github中,您可以看到脚本的第一行是#!/bin/bash。这一行指示要用于脚本的解释器,在本例中是bash shell。换句话说,这个脚本打算用bash外壳来执行。
第35和26行的评论说明了这一点的原因:
这些检查必须在最上面,因为我们从这个脚本中的bash-ism开始。
‘features’是bash shell特有的特性。数组就是一个很好的例子。为了确保使用bash外壳程序,将检查两个条件。
BASH_VERSION变量是由bash shell设置的一个特殊变量。其他shell不设置此变量,因此只需检查它是否已定义就足以继续操作。
POSIXLY_CORRECT变量起作用是因为bash可以在一种称为POSIX模式的不同模式下运行。此模式的存在是为了确保与其他shell,甚至更旧的shell的兼容性。为了获得这种兼容性,bash关闭了它的许多新特性。同样,这会破坏脚本,因此不能从POSIX模式下的bash实例执行脚本。这就是为什么检查是倒转的,即不应该设置POSIXLY_CORRECT。它是在POSIX模式下运行bash时设置的。
正如您在问题中已经指出的,使用/bin/bash运行脚本--正如预期的那样--可以通过检查:定义了BASH_VERSION,而没有定义POSIXLY_CORRECT。
https://unix.stackexchange.com/questions/654350
复制相似问题