2010-12-07 12 views
76

私はこのようなif機能を持っているシェルスクリプトを構築しています:を終了スクリプトのOn Error

if jarsigner -verbose -keystore $keyst -keystore $pass $jar_file $kalias 
then 
    echo $jar_file signed sucessfully 
else 
    echo ERROR: Failed to sign $jar_file. Please recheck the variables 
fi 

... 

は、私は、スクリプトの実行がエラーメッセージを表示した後終了したいです。どのように私はこれを行うことができますか?

答えて

67

exitをお探しですか?

これは、最高のbashガイドです。文脈では http://tldp.org/LDP/abs/html/

if jarsigner -verbose -keystore $keyst -keystore $pass $jar_file $kalias 
then 
    echo $jar_file signed sucessfully 
else 
    echo ERROR: Failed to sign $jar_file. Please recheck the variables 1>&2 
    exit 1 # terminate and indicate error 
fi 

... 
+2

あなたはABSを好きなら、あなたは[BashGuide](http://mywiki.wooledge.org/BashGuide)を好きになる、[BashFAQ]( http://mywiki.wooledge.org/BashFAQ)と[BashPitfalls](http://mywiki.wooledge.org/BashPitfalls)を参照してください。 –

-5

exit 1はあなたが必要とするすべてです。 1は戻りコードなので、たとえば1は正常な実行を意味し、-1は失敗などを意味するように変更できます。

+12

UNIXでは、成功は常に0です。これは 'test'や' && 'や' || 'を使うときに役立ちます。 – mouviciel

+4

mouvicielのコメントを展開するにはシェルスクリプトでは0は常に成功を意味し、1から255は失敗を意味します。 -1が範囲外です(そして、しばしば255と同じ効果を持つので、1のような失敗です)。 – Gilles

+0

@mouviciel、@ Gilles:余分な情報をありがとう。私がbashを扱って以来、しばらくしてきました。 – DGH

252

set -eをスクリプトに入れると、スクリプトはコマンドが失敗すると(つまり、コマンドが0以外の状態を返すとすぐに)終了します。これはあなた自身のメッセージを書くことはできませんが、失敗したコマンドのメッセージだけで十分です。

このアプローチの利点は、自動的であることです。エラーケースを処理することを忘れるリスクはありません。

ステータスが条件付きでテストされたコマンド(if&&、または||など)は、スクリプトを終了しません(そうでない場合、条件付きは無意味です)。障害が問題ではない時折のコマンドのイディオムはcommand-that-may-fail || trueです。 set +eでスクリプトの一部のset -eをオフにすることもできます。

+2

http://mywiki.wooledge.org/BashFAQ/105によると、この機能には、どのコマンドのエラーコードが自動的に終了するかを決定する際に不明瞭で畳み込まれた履歴があります。さらに、 "このルールは、Bashがこの「機能」の非常に滑らかなPOSIX定義を追跡しようとすると、あるBashバージョンから別のBashバージョンに変更されます。私は@Dennis Williamsonとhttp://stackoverflow.com/questions/19622198/what-does-set-e-mean-in-a-bash-scriptの受け入れられた答えに同意します - トラップ 'error_handler' ERRを使用します。それがトラップであっても! – NargothBond

+0

'-x'フラグを' -e'フラグとともに使うと、プログラムが終了している場所でのトレースで十分です。これは、スクリプトのユーザーが開発者でもあることを意味します。 – Alex

33

盲目的に終了する代わりにエラーを処理できるようにするには、set -eを使用する代わりに、ERR擬似信号でtrapを使用します。

#!/bin/bash 
f() { 
    errcode=$? # save the exit code as the first thing done in the trap function 
    echo "error $errorcode" 
    echo "the command executing at the time of the error was" 
    echo "$BASH_COMMAND" 
    echo "on line ${BASH_LINENO[0]}" 
    # do some error handling, cleanup, logging, notification 
    # $BASH_COMMAND contains the command that was being executed at the time of the trap 
    # ${BASH_LINENO[0]} contains the line number in the script of that command 
    # exit the script or return to try again, etc. 
    exit $errcode # or use some other value or do return instead 
} 
trap f ERR 
# do some stuff 
false # returns 1 so it triggers the trap 
# maybe do some other stuff 

他のトラップは通常のUnixシグナルに加えて、他のバッシュ疑似信号RETURNDEBUGを含む他の信号を処理するように設定することができます。ここで

5

はそれを行うための方法です:

#!/bin/sh 

abort() 
{ 
    echo >&2 ' 
*************** 
*** ABORTED *** 
*************** 
' 
    echo "An error occurred. Exiting..." >&2 
    exit 1 
} 

trap 'abort' 0 

set -e 

# Add your script below.... 
# If an error occurs, the abort() function will be called. 
#---------------------------------------------------------- 
# ===> Your script goes here 
# Done! 
trap : 0 

echo >&2 ' 
************ 
*** DONE *** 
************ 
' 
+0

なぜDONEメッセージがstderrに送られますか? – MattBianco

+0

これは一般的な方法ですので、スクリプト出力をstdoutにパイプすることができ、別のプロセスが情報メッセージを途中に残さずに取得できます。 – supercobra

+0

stderrの何かを問題の兆候として扱うことは、おそらく同様に一般的な方法です。 – MattBianco

関連する問題