我正在使用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
测试中失败了(我独立运行了代码片段来验证)。我检查了正在运行的 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 操作系统之间的应用程序可移植性。
我们的服务器没有进行任何更改来解释为什么该脚本不再起作用。我在尚未使用该脚本的服务器上测试了该脚本,并且出现了相同的问题。
服务器都是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
并继续测试BASH_VERSION
和的值) ,就像我昨天所做的那样。EUID
bash
sh
答案1
该错误消息表明您没有使用bash
比 4.0 版本更新的 shell 版本来运行它。据推测,该脚本依赖于bash
shell 实现的功能,这些功能不同于或扩展了 Unix shell 语言的 POSIX 标准规定的功能集。
问题的结尾确认您使用 运行了它sh
,在您的系统上可能是除 之外的其他 shell bash
。即使你sh
是 bash
经过伪装的,它也会是在 POSIX 模式下运行的 shell。
考虑使用 运行脚本bash
,或者,如果脚本的#!
最顶部有一个 - 行,只需使脚本可执行(使用chmod +x scriptname
),然后像 一样运行它./scriptname
。
环境POSIXLY_CORRECT
变量是一个变量,当工具实现的行为与 POSIX 标准规定的行为不同时,它可以帮助实用程序选择行为。
shellbash
在 POSIX 模式下的行为略有不同(即,如果set -o posix
启用,或者 shell 以 启动sh
)。标题为“的部分描述了这些差异Bash POSIX 模式“在bash
手册中。
答案2
用一些上下文细节补充 Kusalananda 的答案。
来自链接的 Github URL,你可以看到脚本的第一行是#!/bin/bash
.该行指示用于脚本的解释器,在本例中是bash
shell。换句话说,该脚本旨在通过bash
shell 执行。
第 35 行和第 26 行的注释清楚地说明了原因:
# These checks need to be right at the top because we start with bash-isms right # away in this script.
“Bash-isms”是特定于bash
shell 的功能。数组就是一个很好的例子。为了确保bash
shell 被使用,需要检查两个条件。
该BASH_VERSION
变量是shell设置的特殊变量bash
。其他 shell 不设置此变量,因此只需检查它是否已定义就足以继续。
该POSIXLY_CORRECT
变量发挥作用是因为bash
它可以在称为 POSIX 模式的不同模式下运行。此模式的存在是为了确保与其他 shell,甚至较旧的 shell 的兼容性。为了获得这种兼容性,bash
请关闭一些较新的功能。同样,这会破坏脚本,因此无法从bash
POSIX 模式下的实例执行脚本。这就是为什么检查是反向的,即POSIXLY_CORRECT
不应设置。它bash
在 POSIX 模式下运行时设置。
正如您在问题中已经指出的那样,按/bin/bash
预期运行脚本可以干净地通过检查:BASH_VERSION
已定义,但POSIXLY_CORRECT
未定义。