コマンドが成功したかどうかを確認する方法は?


235

コマンドの実行中にエラーがあるかどうかを確認する方法はありますか?

例:

test1=`sed -i "/:@/c connection.url=jdbc:oracle:thin:@$ip:1521:$dataBase" $search`
valid $test1

function valid () {
  if $test -eq 1; then
    echo "OK"
    else echo "ERROR" 
  fi
}

私はすでにそれを試みましたが、それは機能していないようです。どうやってやるの


9
好む$(FOO)をバッククォート上で`foo`あなたが巣にそれをすることができるので、それはアポストロフィと区別する方が簡単です。
ユーザー不明

1
ところで、valid呼び出す前に関数()を定義する必要があります。
-wjandrea

回答:


345

戻り値はに保存され$?ます。0は成功を示し、その他はエラーを示します。

some_command
if [ $? -eq 0 ]; then
    echo OK
else
    echo FAIL
fi

他のテキスト値と同様に、将来の比較のために変数に保存できます。

some_command
retval=$?
do_something $retval
if [ $retval -ne 0 ]; then
    echo "Return code was not zero but $retval"
fi

可能な比較演算子については、を参照してくださいman test


それはいいですね...出力エラーを保持できますか?? !! 、この場合、2つのエラーがあるため:コマンドエラー「テキスト」、ファイルが見つかりません、この場合はエラー「テキスト」が失敗しました
-moata_u

@moata_u:私の答えに示すように、変数に値を保存できます。
-Lekensteyn

@moata_u:andの;前にaを置く必要があります: `if ...; その後... その他...; fielsefi
Lekensteyn


1
@Blauhirn [ $? ](または同等のtest $?)は$?、nullではない数値(0、1など)に評価されるため機能しません。参照のためのドキュメントをtest:「EXPRESSIONが省略された場合、 『テスト』はfalseを返す式は単一の引数の場合は引数がそうでない場合はnullとtrueの場合、 『テスト』はfalseを返します。。」
-Lekensteyn

87

コマンドが成功したか失敗したかだけを知る必要がある場合は、テストを気にせず$?、コマンドを直接テストしてください。例えば:

if some_command; then
    printf 'some_command succeeded\n'
else
    printf 'some_command failed\n'
fi

また、出力を変数に割り当てても戻り値は変更されません(もちろん、stdoutがターミナルでない場合に異なる動作をしない限り)。

if output=$(some_command); then
    printf 'some_command succeded, the output was «%s»\n' "$output"
fi

http://mywiki.wooledge.org/BashGuide/TestsAndConditionalsifで詳細を説明しています。


失敗したかどうかのブール値を.iniに保存するなど、分岐以外の何かをしたい場合はどうでしょうか。その場合、出力変数はそれを行いません$?が、そうするため、コマンドを直接テストすることが厳密に優れていると言うのは間違っています。
ティモシースワン

出力を変数に割り当てると、localコマンドを使用するとき、つまり出力でlocal foo=$(false); echo $?;生成するときに戻り値が変更される場合が0あります。ただしlocal、bash関数の内部でのみ関連します。
クロマックス

26
command && echo OK || echo Failed

command画面にエラーが表示される場合、どのように非表示にしますか?
シグル

commandエラーをstderrに書き出す場合は、フォームを使用できますcommand 2> /dev/null && echo OK || echo Failed2> /dev/nullリダイレクトは出力を標準エラー出力します/dev/null。ただし、一部のユーティリティは(これは悪い習慣ですが)stdoutにエラーを書き込みます。この場合、リダイレクトから2を省略できますが、コマンドからの出力は失われます。成功を確認するこの方法は、単純な3項論理には適していますが、より複雑な動作を行うには$?、コマンドの成功を確認するかif、@ geirhaの回答で概説されているブロックメソッドを使用するのが最善です。
ベンダー最大

17

$?前のコマンドの終了ステータスを含める必要があり、エラーがない場合はゼロにする必要があります。

そのため、次のようなものです。

cd /nonexistant
if [ $? -ne 0 ]
then
    echo failed
else
    echo success!
fi

ほとんどの場合、&&コンストラクトを使用して、互いに依存する必要のあるコマンドをチェーンする方が簡単です。そうcd /nonexistant && echo success!考えていない &&前にコマンドブレークので、成功をエコー。これの当然の結果は||、あるcd /nonexistant || echo fail でしょう CDが失敗したため失敗エコー。(これは、前のコマンドが失敗した場合にスクリプトを終了する|| exitのようなものを使用する場合に役立ちます。)


それはいいですね...出力エラーを保持できますか?? !! 、この場合、私は2つのエラーがあるため:コマンドエラー「テキスト」、ファイルが見つかりません、この場合は失敗した「テキスト」エラー
-moata_u


5
command && echo $? || echo $?

という意味command; echo $?ですか?
ハビエルブッツィ

いいえ、私の行は正しいです。成功か失敗かに関係なく、実際の結果コードを数値として提供します。
modrobert

1
わかりました、これらの違いを私に説明してください:true && echo $? || echo $?/ true; echo $?およびfalse && echo $? || echo $?/ false; echo $?-あなたは見つけるでしょう、彼らはまったく同じことをします:D
ハビエル・ブッジ

はい、同じ結果ですが、条件はありません。元の質問は「コマンドが成功したかどうかを確認する方法」でした。これは以前の回答に基づいていました。私はより良い例は以下のようになり推測:command && echo "success: $?" || echo "fail: $?"
modrobert

5

それはそれを注意すべきであるif...then...fi&&/ ||私たちは(成功時には0)をテストしたいコマンドで返される終了ステータスでアプローチのお得な情報のタイプ。ただし、一部のコマンドは、コマンドが失敗した場合、または入力を処理できなかった場合、ゼロ以外の終了ステータスを返しません。これは、これらの特定のコマンドでは通常のアプローチif&&/ ||アプローチが機能しないことを意味します。

たとえば、Linuxでは、GNU fileは引数として存在しないファイルを受け取り、find指定されたユーザーを見つけることができなかった場合、0で終了します。

$ find . -name "not_existing_file"                                          
$ echo $?
0
$ file ./not_existing_file                                                  
./not_existing_file: cannot open `./not_existing_file' (No such file or directory)
$ echo $?
0

このような場合には、我々は状況を扱うことができる1個の潜在的な方法は、読書であるstderr/ stdinメッセージ、例えばによって返されたものfileのコマンド、またはのようにコマンドの出力を解析しますfind。そのために、caseステートメントを使用できます。

$ file ./doesntexist  | while IFS= read -r output; do                                                                                                                  
> case "$output" in 
> *"No such file or directory"*) printf "%s\n" "This will show up if failed";;
> *) printf "%s\n" "This will show up if succeeded" ;;
> esac
> done
This will show up if failed

$ find . -name "doesn'texist" | if ! read IFS= out; then echo "File not found"; fi                                                                                     
File not found

(これは、unix.stackexchange.comの関連する質問に関する私自身の回答の再投稿です)


1

他の多くの回答で述べた$?ように、次のような簡単なテストが行われます

if [ $? -eq 0 ]; then something; fi

コマンドが失敗したかどうかをテストする場合は、次のように短いバージョンを使用できますbash(ただし、おそらくは過剰です)。

if (($?)); then something; fi

これは(( ))算術モードを使用することで機能するため、コマンドが返された場合success、つまり$? = 0、テストは((0))asとして評価されfalse、そうでない場合はを返しtrueます。

成功をテストするには、次を使用できます。

if ! (($?)); then something; fi

しかし、それは最初の例よりもずっと短くはありません。


1
建設的な批判?
アフナ


-2

if [$(command)]; 次に、「成功」をエコーし​​ます。fi


3
true成功しif [ $(true) ]; then echo "succeed"; fiますsucceedが、印刷されません。実際、これはcommand成功したかどうかをチェックしません。geirhaの投稿のif commandように使用するだけです。あるコマンド置換。は条件式です。不在ワード分割とファイル名の拡張があれば、これは基本的にテスト出力を持っていました。$( )[ ]command
エリアカガン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.