`set -e`を指定したbashスクリプトは`…&&… `コマンドで停止しません


13

最初のエラーでbashスクリプトset -e停止するために使用します

次のコマンドを使用しない限り、すべて正常に動作し&&ます。

$ cat script
set -e
cd not_existing_dir && echo 123
echo "I'm running! =P"
$
$ ./script
./script: line 2: cd: not_existing_dir: No such file or directory
I'm running! =P
$

と比べて:

$ cat script
set -e
cd not_existing_dir
echo "I'm running! =P"
$
$ ./script
./script: line 2: cd: not_existing_dir: No such file or directory
$

最初の例はまだエコーI'm running!しますが、2番目の例はエコーしません。なぜ彼らは異なる振る舞いをするのですか?

UPD。同様の質問:https : //stackoverflow.com/questions/6930295/set-e-and-short-tests


最初の例で何が起こると思いますか?
フラップ

@Flup cdコマンドが失敗した後、スクリプトが停止する予定です
907th

1
動作が驚くべき場所の一般的な議論については、BashFAQ#105を参照してくださいset -e
チャールズダフィー

回答:


9

これは文書化された動作です。bashの(1)のmanページはのために、と言いset -e

失敗したコマンドは、すぐに次のコマンドリストの一部である場合、シェルは終了しないwhileか、untilキーワードを、次の試験の一部ifまたはelif予約語、 中に実行されたコマンドの一部&&または||リスト 最終以下のコマンドを除い&&たり||、任意のパイプラインで最後のコマンド、またはでコマンドの戻り値が反転して!いる場合
[エンファシスが追加されました。]

また、POSIX Shell Command Language Specification は、これが正しい動作であることを確認しています。

-e以下の化合物のリストを実行するときの設定は無視されなければならないwhileuntilif、またはelif予約語で始まるパイプライン!予約語、または最後以外のAND-ORリストの任意のコマンド。

そして、セクション2.9.3 を一覧表示し、その文書の定義の

AND-ORリストは、演算子 " &&"および " ||"で区切られた1つ以上のパイプラインのシーケンスです。


9

このset -eオプションは状況によっては効果がありません。これは標準の動作であり、POSIX準拠のシェル間で移植可能です。


失敗したコマンドはパイプラインの一部です:

false | true; echo printed

印刷されますprinted

そして、パイプライン自体の障害のみが考慮されます。

true | false; echo 'not printed'

何も印刷しません。


以下の化合物のリストで失敗したコマンドの実行whileuntilifelif予約語で始まるパイプライン!の一部として予約語、または任意のコマンド&&または||:最後のものを除くリスト

false || true; echo printed

最後のコマンドが失敗してもset -e影響を受けます:

true && false; echo 'not printed'

サブシェルは、化合物のコマンドに失敗します。

(false; echo 'not printed') | cat -; echo printed

ありがとうございました!これは、使用に明確になりますecho "printed"し、echo "not_printed"あなたの例では(代わりにecho 1)。
907th

3
異なるシェルと同じシェルの異なるバージョンでさえもYMMVであるにもかかわらず、ではなくでset -e終了することに注意してください。バージポールには触れず、代わりに適切なエラー処理を行います。(false && true); echo not here{ false && true; }; echo hereset -e
ステファンシャゼラス16

1

私の推測では、if-then条件は全体としてtrueと評価されます。

私は試した

set -e
if cd not_existing_dir
then  echo 123
fi
echo "I'm running! =P"

誰が与える

-bash: cd: not_existing_dir: No such file or directory
I'm running! =P

エラーコードはif条件によってキャッチされるため、bashは実行の終了をトリガーしません。


しかし、私は使用しませんif ... fi
第九百七

これは暗黙の場合です。
アーケマー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.