いくつかのコマンドを呼び出すBash Shellスクリプトがあります。いずれかのコマンドがゼロ以外の値を返す場合は、シェルスクリプトを自動的に終了値1で終了させます。
各コマンドの結果を明示的にチェックしなくてもこれは可能ですか?
例えば.
dosomething1
if [[ $? -ne 0 ]]; then
exit 1
fi
dosomething2
if [[ $? -ne 0 ]]; then
exit 1
fi
これをスクリプトの先頭に追加します。
set -e
これにより、単純なコマンドがゼロ以外の終了値で終了した場合に、シェルは直ちに終了します。単純なコマンドは、if、while、またはuntilテストの一部ではないコマンド、または&&または||の一部ではないコマンドです。リスト。
詳細は、 "set"内部コマンドの bash(1)のマニュアルページ を参照してください。
私は個人的にはほとんどすべてのシェルスクリプトを "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 set -e set -o pipefail ./ configure | tee configure.log make
あなたの例のif文は不要です。このようにしてください。
dosomething1 || exit 1
Ville Laurikariのアドバイスを受けてset -e
を使用する場合、いくつかのコマンドではこれを使用する必要があります。
dosomething || true
|| true
は、コマンドが失敗してもコマンドパイプラインにtrue
の戻り値を持たせるため、-e
オプションを指定してもスクリプトは強制終了されません。
終了時にクリーンアップが必要な場合は、擬似シグナルERRとともに 'trap'を使用することもできます。これは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オプションによる終了など、何らかの理由でスクリプトが終了すると、トラップが実行されます。
先頭に-e
またはset -e
を付けて実行します。
set -u
も見てください。
$?
変数はめったに必要とされません。擬似イディオム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
#!/bin/bash -e
十分なはずです。
のような表現
dosomething1 && dosomething2 && dosomething3
コマンドの1つがゼロ以外の値で戻ったときに処理を停止します。たとえば、次のコマンドは "done"を印刷しません。
cat nosuchfile && echo "done"
echo $?
1