-e
オプションを設定すると、bash(およびダッシュ)の動作が混乱します。
簡単な例:
#!/bin/bash -e
func() {
false && true
}
false && true
echo "1"
func
echo "2"
出力:
1
予想出力:
1
2
最初の発生は期待どおりに機能しますが、2番目の発生(関数の内部)ではすぐに終了します。文書を検索しましたが、他の動作の説明が見つかりませんでした。これの背後に何らかの理由がありますか、それともバグですか?私はこれをbashとdashで同じ結果でテストしました。
Bashのマニュアルページによると:
-e
パイプ(単一の単純コマンドで構成できます)、リスト、または複合コマンド(上記のSHELL GRAMMARを参照)がゼロ以外の状態で終了した場合は、直ちに終了してください。失敗したコマンドが、またはキーワードwhile
の直後のコマンドのリストの一部であるか、予約until
語の後のテストの一部である場合、またはリストで実行されるコマンドの一部である場合(最後または後続のコマンドを除く)、シェルは終了しません。パイプラインの最後のコマンドまたはコマンドの戻り値は同じです。コマンドが無視されたときに失敗したため、サブシェルの外部の複合コマンドがゼロ以外の状態を返した場合、シェルは終了しません。トラップが設定されている場合、シェルが終了する前に実行されます。このオプションは、シェル環境と各サブシェル環境(上記のコマンドの実行環境を参照)に個別に適用され、サブシェルのすべてのコマンドを実行する前にサブシェルを終了できます。if
elif
&&
||
&&
||
!
-e
ERR
複合コマンドまたはシェル関数が無視されたコンテキストで実行される場合、複合コマンド
-e
または関数の本文内で実行されるすべてのコマンドは、この設定が設定され、コマンドが失敗状態を返しても-e
この設定の影響を受けません。-e
複合コマンドまたはシェル関数が無視されたコンテキストで実行された-e
ときに設定されると、-e
複合コマンドまたは関数呼び出しを含むコマンドが完了するまで設定は適用されません。
答え1
func
終了ステータスが0ではないため、スクリプトが戻ったときに終了します。スクリプトは内部的に終了しませんfunc
。
リストfalse && true
は影響を受けず、-e
スクリプトは終了せず、スクリプトの主要部分にも機能もありません。
ただし、false
関数内の関数は関数の終了状態をゼロ以外の値に設定するため、関数が返されるとシェルは終了します。
スクリプトを次のように単純化できます。
#!/bin/bash -e
false && true
echo "1"
false
echo "2"
false && true
関数のリストがスクリプトを終了しないことを確認するために、関数のゼロ戻り値をテストすることもできます。
#!/bin/bash -e
func() {
false && true
return 0
}
false && true
echo "1"
func
echo "2"
この出力の実行
1
2
答え2
sについて質問していないので直接関係はありませんがtrap
...
ERRトラップと設定-Eと設定-e
このスクリプトには関数にエラーがあるためset -E
含まれません。set -e
$ cat trap_test.sh
#!/usr/bin/env bash
trap 'echo "Error on line $LINENO. Exit code: $?" >&2' ERR
myfunc() {
noSuchCommand
echo OK
}
myfunc
その後、-Eと-eの組み合わせを確認できます。
- 指定なし:トラップなし、早期終了なし
$ bash trap_test.sh; echo "exit status: $?" trap_test.sh: line 6: noSuchCommand: command not found OK exit status: 0
- -e: 早く終了します。関数にトラップがありません。
$ bash -e trap_test.sh; echo "exit status: $?" trap_test.sh: line 6: noSuchCommand: command not found exit status: 127
- -E、関数エラーによるトラップ
$ bash -E trap_test.sh; echo "exit status: $?" trap_test.sh: line 6: noSuchCommand: command not found Error on line 6. Exit code: 127 OK exit status: 0
- 早期終了と罠/
$ bash -eE trap_test.sh; echo "exit status: $?" trap_test.sh: line 6: noSuchCommand: command not found Error on line 6. Exit code: 127 exit status: 127