[]testがこのスクリプトに失敗するのはなぜですか?

[]testがこのスクリプトに失敗するのはなぜですか?

次の2つのスクリプトを考えてみましょう。

run.sh:

#!/bin/bash
set -euo pipefail
. "$(dirname $(realpath $BASH_SOURCE))"/init-sudo-script.sh

init-sudo-script.sh

[ ${#BASH_SOURCE[@]} -eq 1 ]\
    && echo "must be sourced by another script."\
    && exit 10

[ $EUID -ne 0 ]\
    && echo "must be executed as root."\
    && exit 20

これは正確で、これが私が期待するものです。

$ ./run.sh
must be executed as root.
$ echo $?
20

しかし、理解できません。

$ sudo ./run.sh
$ echo $?
1

問題は、[ $EUID -ne 0 ]スクリプトを削除すると機能するためであることがわかります。

また、set -eエラーが発生するとスクリプトが終了することも理解しています。

私が理解していないのは、なぜ最初のガード条件([ ${#BASH_SOURCE[@]} -eq 1 ])が失敗したときに1で終了しないのか、そして2番目のガード条件が終了する理由です。

ここで何が起こっているのか理解する人はいますか?

===更新===

期待どおりに機能させる方法を見つけました。

if [ $EUID -ne 0 ]; then
    echo "must be executed as root."\
    && exit 20
fi

私はそれを残してBashをより良くするために投資しています。したがって、誰かが何が起こっているのかを明確にすることができれば、喜んで聞きたいのです。

ベストアンサー1

また、set -eエラーが発生するとスクリプトが終了することも理解しています。

「何も間違っていませんでした」ではありません。例外があり、そのうちの1つは次のとおりです。

失敗したコマンドがまたは&&リストで実行されたコマンドの[...]の一部である場合、||シェルは次の最後または[...]コマンドを除いて終了しません。&&||

源泉)

失敗すると、[ ${#BASH_SOURCE[@]} -eq 1 ]シェルは終了しませんset -e

同様[ $EUID -ne 0 ]に失敗すると、シェルは終了しませんがset -e台本が終わったからつまり、実行することはもう残っていないからです。これにより、スクリプトの終了状態は、最後に実行されたコマンドの終了状態になります[。それがあなたが得る理由です1

:テストが完了したら(常に成功した無修正コマンド)を入れてinit-sudo-script.shテストを再実行してください。最後のコマンドがあるためsudo ./run.sh返されます。0:


if終了ステータスは次のとおりであるため、更新されたコードは異なりますif

[...] 条件が true でテストされていない場合は 0 です。

源泉)

おすすめ記事