私は一連のコマンドを実行する必要があるシェルスクリプトを書いており、すべてのコマンドは以前のすべてのコマンドに依存しています。コマンドが失敗した場合、スクリプト全体が失敗し、exit関数を呼び出します。各コマンドの終了コードを確認することはできますが、有効にできるモードがあるかどうか、またはbashに自動的にそれを実行させる方法があるかどうか疑問に思っています。
たとえば、次のコマンドを実行します。
cd foo || myfunc
rm a || myfunc
cd bar || myfunc
rm b || myfunc
これらのコマンドを実行する前に、なんらかの理由でシェルに信号を送って、失敗した場合にmyfuncを呼び出す必要があるため、代わりに次のようなよりクリーンなものを書くことができる方法があります。
cd foo
rm a
cd bar
rm b
「すべてのコマンドは前のすべてのコマンドに依存します。コマンドが失敗した場合、スクリプト全体が失敗するはずです」という言葉をとれば、エラーを処理する特別な機能。
必要なのは、コマンドを&&
演算子と||
演算子で連鎖させることだけです。これにより、作成した内容が正確に実行されます。
たとえば、前のコマンドのanyが壊れた場合、このチェーンは壊れて「何か問題が発生しました」と出力します(bashは左から右に読み取ります)
cd foo && rm a && cd bar && rm b || echo "something went wrong"
実際の例(実際のデモのためにdir foo、file a、dir bar、file bを作成しました):
gv@debian:/home/gv/Desktop/PythonTests$ cd foo && rm a && cd bar && rm bb || echo "something is wrong"
rm: cannot remove 'bb': No such file or directory
something is wrong #mind the error in the last command
gv@debian:/home/gv/Desktop/PythonTests$ cd foo && rm aa && cd bar && rm b || echo "something is wrong"
rm: cannot remove 'aa': No such file or directory
something is wrong #mind the error in second command in the row
そして最後に、すべてのコマンドが正常に実行された場合(終了コード0)、スクリプトは続行します。
gv@debian:/home/gv/Desktop/PythonTests$ cd foo && rm a && cd bar && rm b || echo "something is wrong"
gv@debian:/home/gv/Desktop/PythonTests/foo/bar$
# mind that the error message is not printed since all commands were successful.
&&を使用すると、前のコマンドがコード0で終了した場合に次のコマンドが実行されます。
チェーン内のいずれかのコマンドが失敗した場合、コマンド/スクリプト/以下のすべてが||実行されます。
そして記録のためだけに、壊れたコマンドに応じて異なるアクションを実行する必要がある場合は、以前のコマンドの終了コードを報告する$?
の値を監視することにより、クラシックスクリプトでそれを行うこともできます(戻りコマンドが正常に実行された場合はゼロ、コマンドが失敗した場合はその他の正の数)
例:
for comm in {"cd foo","rm a","cd bbar","rm b"};do #mind the error in third command
eval $comm
if [[ $? -ne 0 ]];then
echo "something is wrong in command $comm"
break
else
echo "command $comm executed succesful"
fi
done
出力:
command cd foo executed succesfull
command rm a executed succesfull
bash: cd: bbar: No such file or directory
something is wrong in command cd bbar
ヒント:「bash:cd:bbar:No such file ...」というメッセージを抑制するには、eval $comm 2>/dev/null
を適用します