GitHub のスクリプトを使用してテストしていますmigrate2rocky.sh
:
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 系 OS 間でのアプリケーションの移植性を容易にするための標準セットです。
スクリプトが機能しなくなった理由を説明するために、サーバーに変更は加えられていません。まだスクリプトを使用していないサーバーでスクリプトをテストしましたが、同じ問題が発生します。
サーバーはすべて 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
エラー メッセージは、リリース 4.0 より新しいシェルのリリースでスクリプトを実行していないことを示していますbash
。おそらく、スクリプトは、bash
シェルが実装する機能に依存しており、その機能は Unix シェル言語の POSIX 標準で規定されている機能セットとは異なるか、その機能を拡張しています。
質問の最後では、 を使用して実行したことが確認されていますがsh
、これはシステム上では 以外のシェルである可能性があります。 が偽装されている bash
場合でも、POSIX モードで実行されているシェルになります。sh
bash
スクリプトを を使用して実行することを検討してくださいbash
。または、スクリプトの#!
先頭に 行がある場合は、スクリプトを実行可能にして ( を使用してchmod +x scriptname
)、 のように実行します./scriptname
。
環境POSIXLY_CORRECT
変数は、ツールが POSIX 標準で規定されている動作とは異なる動作を実装する場合に、ユーティリティが動作を選択するのに役立つ変数です。
POSIX モードでは、シェルbash
の動作が若干異なります (つまり、set -o posix
が有効になっている場合、またはシェルが として起動されている場合sh
)。違いについては、「Bash POSIX モードマニュアルの「」を参照してくださいbash
。
答え2
Kusalananda の回答をいくつかの文脈的詳細で補足します。
からリンクされたGithub URLを見ると、スクリプトの最初の行が であることがわかります#!/bin/bash
。この行は、スクリプトに使用されるインタープリタを示しています。この場合はシェルですbash
。つまり、このスクリプトはbash
シェルで実行されることを意図しています。
その理由は、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
シェルに固有の機能です。配列はその良い例です。bash
シェルが使用されていることを確認するために、2 つの条件がチェックされます。
このBASH_VERSION
変数は、シェルによって設定される特別な変数ですbash
。他のシェルはこの変数を設定しないので、定義されていることを確認するだけで続行できます。
この変数は、POSIX モードと呼ばれる別のモードで実行できるPOSIXLY_CORRECT
ため、役立ちます。このモードは、他のシェル、さらには古いシェルとの互換性を確保するために存在します。この互換性を確保するために、新しい機能のいくつかがオフになっています。繰り返しますが、これによってスクリプトが壊れるため、POSIX モードのインスタンスからスクリプトを実行することはできません。これが、チェックが反転されている理由です。つまり、チェックは設定しないでください。POSIX モードで実行するときに設定されます。bash
bash
bash
POSIXLY_CORRECT
bash
質問で既に指摘されているように、意図したとおりにスクリプトを実行すると、定義されているかどうかの/bin/bash
チェックに問題なく合格します。BASH_VERSION
POSIXLY_CORRECT