276

私はシェルスクリプトの初心者です。メッセージを出力し、コマンドが失敗した場合にスクリプトを終了したい。私はもう試した:

my_command && (echo 'my_command failed; exit)

しかし、それは機能しません。スクリプトのこの行に続く命令を実行し続けます。私はUbuntuとbashを使用しています。

4

9 に答える 9

501

試す:

my_command || { echo 'my_command failed' ; exit 1; }

4つの変更:

  • &&に変更||
  • { }の代わりに使用( )
  • ;後に紹介しexit
  • {前後のスペース}

||メッセージを出力し、コマンドが失敗した場合(ゼロ以外の値で終了する場合)にのみ終了するため、ではなくを必要とします&&

cmd1 && cmd2

成功すると実行さcmd2れますcmd1(exit value 0)。一方

cmd1 || cmd2

失敗すると実行さcmd2cmd1ます(終了値がゼロ以外)。

を使用( )すると、コマンドがサブシェルで実行され、そこからaを呼び出すと、元のシェルexitではなくサブシェルが終了するため、元のシェルで実行が続行されます。

この使用を克服するには{ }

最後の2つの変更は、bashで必要です。

于 2010-09-29T14:35:17.313 に答える
160

他の回答は直接の質問をうまくカバーしていますが、を使用することにも興味があるかもしれませんset -e。これにより、(テストなどの特定のコンテキスト以外でif)失敗したコマンドがあると、スクリプトが中止されます。特定のスクリプトでは、非常に便利です。

于 2010-09-29T16:05:43.083 に答える
93

スクリプト内のすべてのコマンドでその動作が必要な場合は、次を追加するだけです。

set -e 
set -o pipefail

スクリプトの最初に。このオプションのペアは、コマンドがゼロ以外の終了コードで戻るたびに終了するようにbashインタープリターに指示します。pipefail(必要な理由の詳細については、 http://petereisentraut.blogspot.com/2010/11/pipefail.htmlを参照してください)

ただし、これでは終了メッセージを印刷することはできません。

于 2013-10-19T18:33:18.073 に答える
77

また、各コマンドの終了ステータスはシェル変数$?に格納されており、コマンドの実行直後に確認できます。ゼロ以外のステータスは失敗を示します。

my_command
if [ $? -eq 0 ]
then
    echo "it worked"
else
    echo "it failed"
fi
于 2010-09-29T14:40:59.570 に答える
17

私は次のイディオムをハックしました:

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 ];...行を続けます。(もちろん、必要に応じてそのエラーメッセージを編集できます。)

于 2012-12-17T22:58:59.137 に答える
12

提供my_commandは標準的に設計されています。つまり、成功すると0を返し、それ&&はあなたが望むものとは正反対です。あなたが欲しい||

また(、bashでは正しくないように思われますが、現在の場所から試すことはできません。教えて。

my_command || {
    echo 'my_command failed' ;
    exit 1; 
}
于 2010-09-29T14:34:45.210 に答える
6

終了エラーのステータスを保持し、1行に1つのコマンドを含む読み取り可能なファイルを作成する場合は、次を使用することもできます。

my_command1 || exit $?
my_command2 || exit $?

ただし、これによって追加のエラーメッセージが出力されることはありません。ただし、場合によっては、とにかく失敗したコマンドによってエラーが出力されます。

于 2018-03-08T14:20:13.987 に答える
6

シェルビルトインにより、シグナルのtrapキャッチ、およびコマンド実行の失敗(つまり、ゼロ以外の戻りステータス)を含むその他の有用な条件が可能になります。したがって、すべてのコマンドの戻りステータスを明示的にテストしたくない場合はtrap "your shell code" ERR、コマンドがゼロ以外のステータスを返すたびにシェルコードが実行されます。例えば:

trap "echo script failed; exit 1" ERR

失敗したコマンドをキャッチする他の場合と同様に、パイプラインには特別な処理が必要であることに注意してください。上記はキャッチしませんfalse | true

于 2018-03-08T21:50:32.617 に答える
2

exitスクリプトは他の場所(ターミナルなど)から供給される可能性があるため、直接使用するのは難しい場合があります。私は代わりにサブシェルを使用することを好みますset -e(さらにエラーはcoutではなくcerrに入るはずです):

set -e
ERRCODE=0
my_command || ERRCODE=$?
test $ERRCODE == 0 ||
    (>&2 echo "My command failed ($ERRCODE)"; exit $ERRCODE)
于 2020-12-31T10:33:19.527 に答える