回答:
これをスクリプトの最初に追加します。
set -e
これにより、単純なコマンドがゼロ以外の終了値で終了した場合、シェルは即座に終了します。単純なコマンドとは、if、while、またはuntil testの一部ではない任意のコマンド、または&&または||の一部です。リスト。
詳細については、「set」内部コマンドのbash(1)のマニュアルページを参照してください。
私はほとんどすべてのシェルスクリプトを「set -e」で開始しています。途中で何かが失敗し、残りのスクリプトの前提が破られた場合、スクリプトを頑固に続行するのは本当に面倒です。
bash script.sh
ます。
set -e; tf() { false; }; tf; echo 'still here'
。set -e
の本体内になくてもtf()
、実行は中止されます。おそらく、それはサブシェルにset -e
継承されていないと言うつもりでした。
受け入れられた回答に追加するには:
set -e
パイプがある場合は特に、時には十分ではないことを覚えておいてください。
たとえば、次のスクリプトがあるとします。
#!/bin/bash
set -e
./configure > configure.log
make
...これは期待どおりに機能しますconfigure
。エラーにより実行が中止されます。
明日は一見取るに足らない変更を加えます:
#!/bin/bash
set -e
./configure | tee configure.log
make
...そして今、それは機能しません。これはここで説明されており、回避策(Bashのみ)が提供されています。
#!/ bin / bash セット-e set -o pipefail ./configure | tee configure.log 作る
pipefail
一緒に行くことの重要性を説明していただきありがとうございますset -o
!
例のifステートメントは不要です。次のようにしてください:
dosomething1 || exit 1
Ville Laurikariのアドバイスを取り入れて使用する場合set -e
は、一部のコマンドでこれを使用する必要があります。
dosomething || true
|| true
コマンドパイプラインが持つようになりますtrue
ので、コマンドが失敗した場合でも、戻り値を-e
オプションは、スクリプトを殺すことはありません。
set -e
はbash中心ではありません-元のBourne Shellでもサポートされています。
終了時に行う必要があるクリーンアップがある場合は、疑似信号ERRで「トラップ」を使用することもできます。これは、INTまたは他の信号をトラップするのと同じように機能します。コマンドがゼロ以外の値で終了すると、bashはERRをスローします。
# Create the trap with
# trap COMMAND SIGNAME [SIGNAME2 SIGNAME3...]
trap "rm -f /tmp/$MYTMPFILE; exit 1" ERR INT TERM
command1
command2
command3
# Partially turn off the trap.
trap - ERR
# Now a control-C will still cause cleanup, but
# a nonzero exit code won't:
ps aux | grep blahblahblah
または、特に「set -e」を使用している場合は、EXITをトラップできます。トラップは、スクリプトが正常終了、割り込み、-eオプションによる終了など、何らかの理由で終了したときに実行されます。
$?
変数はほとんど必要ありません。疑似イディオムcommand; if [ $? -eq 0 ]; then X; fi
は、常にと書く必要がありますif command; then X; fi
。
$?
必要なケースは、複数の値に対してチェックする必要がある場合です。
command
case $? in
(0) X;;
(1) Y;;
(2) Z;;
esac
または$?
再利用またはその他の操作が必要な場合:
if command; then
echo "command successful" >&2
else
ret=$?
echo "command failed with exit code $ret" >&2
exit $ret
fi
上部-e
またはset -e
上部で実行します。
も見てくださいset -u
。
help set
:-u
設定されていない変数への参照をエラーとして扱います。
set -u
かset -e
、または両方ですか?@lumpynose
Mark Edgarsの入力に追加の質問があり、ここに追加の例があり、トピック全体に触れているので、参照用に別のものを投入するだけです。
[[ `cmd` ]] && echo success_else_silence
これはcmd || exit errcode
誰かが示したのと同じです。
例えば。マウントされている場合、パーティションがマウント解除されていることを確認したい:
[[ `mount | grep /dev/sda1` ]] && umount /dev/sda1
[[
cmd`]] `は同じものではありません。コマンドの終了ステータスに関係なく、コマンドの出力が空の場合はfalse、それ以外の場合はtrueです。
set -e
、set -u
(またはset -eu
)も実行します。-u
存在しない変数にアクセスして、診断なしで空白の値を生成できる、ばかげたバグを隠す動作に終止符を打つ。