
我正在使用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 之外的其他 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
未定義。