私はこのスクリプトを実行しようとしています:
#!/bin/bash -e
{
echo "Doing something";
will_fail # like `false`
echo "Worked";
} || echo "Failed"
驚いたことに、will_fail
は失敗しましたが、コマンドラインに「Failed」と表示されず、「Worked」と表示されました。
will_fail
が失敗した後、複合コマンドがエラーで終了しなかったのはなぜですか?
複合コマンドの終了ステータスは、{ ...; }
で実行されている最後のコマンドの終了ステータス(Failed
)であるため、echo
は出力されません。 echo
は成功するため、複合コマンドは終了ステータスがゼロで終了します。
以下は3つの文字列を出力します。
{ echo "Do something"; echo "Worked"; false; } || echo "Failed"
から POSIX標準 :
特に明記されていない限り、コマンドの終了ステータスは、コマンドによって実行された最後の単純なコマンドの終了ステータスになります。
ここで起こっていることがいくつかあります(要約):
set -e
をアクティブにして実行します。これにより、コマンドがゼロ以外の終了ステータスを返した場合(大まかに言えば)、シェルが終了します。ただし、will_fail
コマンドは||
リストの一部(一部である複合コマンド)であるため、ここでは適用されません(最後ではありません)。
繰り返しますが、 POSIX標準 (私の強調)から:
パイプラインである
while
、until
、if
、またはElif
予約語に続く複合リストを実行する場合、-e
設定は無視されます。!
予約語、または最後以外のAND-ORリストの任意のコマンドで始まります。
||
リストの最後の単純なコマンドはecho "Failed"
です。これが、複合コマンドの全体的な終了ステータスを決定するものです。正常に実行されるため(また、will_fail
によってシェルが終了しないため)、ステータスはゼロになります。これは、||
の反対側が実行されないことを意味します。