私はシェルスクリプトの初心者です。メッセージを出力し、コマンドが失敗した場合にスクリプトを終了したい。私はもう試した:
my_command && (echo 'my_command failed; exit)
しかし、それは機能しません。スクリプトのこの行に続く命令を実行し続けます。私はUbuntuとbashを使用しています。
私はシェルスクリプトの初心者です。メッセージを出力し、コマンドが失敗した場合にスクリプトを終了したい。私はもう試した:
my_command && (echo 'my_command failed; exit)
しかし、それは機能しません。スクリプトのこの行に続く命令を実行し続けます。私はUbuntuとbashを使用しています。
試す:
my_command || { echo 'my_command failed' ; exit 1; }
4つの変更:
&&
に変更||
{ }
の代わりに使用( )
;
後に紹介しexit
、{
前後のスペース}
||
メッセージを出力し、コマンドが失敗した場合(ゼロ以外の値で終了する場合)にのみ終了するため、ではなくを必要とします&&
。
cmd1 && cmd2
成功すると実行さcmd2
れますcmd1
(exit value 0
)。一方
cmd1 || cmd2
失敗すると実行さcmd2
れcmd1
ます(終了値がゼロ以外)。
を使用( )
すると、コマンドがサブシェルで実行され、そこからaを呼び出すと、元のシェルexit
ではなくサブシェルが終了するため、元のシェルで実行が続行されます。
この使用を克服するには{ }
最後の2つの変更は、bashで必要です。
他の回答は直接の質問をうまくカバーしていますが、を使用することにも興味があるかもしれませんset -e
。これにより、(テストなどの特定のコンテキスト以外でif
)失敗したコマンドがあると、スクリプトが中止されます。特定のスクリプトでは、非常に便利です。
スクリプト内のすべてのコマンドでその動作が必要な場合は、次を追加するだけです。
set -e
set -o pipefail
スクリプトの最初に。このオプションのペアは、コマンドがゼロ以外の終了コードで戻るたびに終了するようにbashインタープリターに指示します。pipefail
(必要な理由の詳細については、 http://petereisentraut.blogspot.com/2010/11/pipefail.htmlを参照してください)
ただし、これでは終了メッセージを印刷することはできません。
また、各コマンドの終了ステータスはシェル変数$?に格納されており、コマンドの実行直後に確認できます。ゼロ以外のステータスは失敗を示します。
my_command
if [ $? -eq 0 ]
then
echo "it worked"
else
echo "it failed"
fi
私は次のイディオムをハックしました:
echo "Generating from IDL..."
idlj -fclient -td java/src echo.idl
if [ $? -ne 0 ]; then { echo "Failed, aborting." ; exit 1; } fi
echo "Compiling classes..."
javac *java
if [ $? -ne 0 ]; then { echo "Failed, aborting." ; exit 1; } fi
echo "Done."
各コマンドの前に有益なエコーを付け、各コマンドの後に同じ
if [ $? -ne 0 ];...
行を続けます。(もちろん、必要に応じてそのエラーメッセージを編集できます。)
提供my_command
は標準的に設計されています。つまり、成功すると0を返し、それ&&
はあなたが望むものとは正反対です。あなたが欲しい||
。
また(
、bashでは正しくないように思われますが、現在の場所から試すことはできません。教えて。
my_command || {
echo 'my_command failed' ;
exit 1;
}
終了エラーのステータスを保持し、1行に1つのコマンドを含む読み取り可能なファイルを作成する場合は、次を使用することもできます。
my_command1 || exit $?
my_command2 || exit $?
ただし、これによって追加のエラーメッセージが出力されることはありません。ただし、場合によっては、とにかく失敗したコマンドによってエラーが出力されます。
シェルビルトインにより、シグナルのtrap
キャッチ、およびコマンド実行の失敗(つまり、ゼロ以外の戻りステータス)を含むその他の有用な条件が可能になります。したがって、すべてのコマンドの戻りステータスを明示的にテストしたくない場合はtrap "your shell code" ERR
、コマンドがゼロ以外のステータスを返すたびにシェルコードが実行されます。例えば:
trap "echo script failed; exit 1" ERR
失敗したコマンドをキャッチする他の場合と同様に、パイプラインには特別な処理が必要であることに注意してください。上記はキャッチしませんfalse | true
。
exit
スクリプトは他の場所(ターミナルなど)から供給される可能性があるため、直接使用するのは難しい場合があります。私は代わりにサブシェルを使用することを好みますset -e
(さらにエラーはcoutではなくcerrに入るはずです):
set -e
ERRCODE=0
my_command || ERRCODE=$?
test $ERRCODE == 0 ||
(>&2 echo "My command failed ($ERRCODE)"; exit $ERRCODE)