web-dev-qa-db-ja.com

コマンドが成功または失敗した場合に条件付きで何かを行う方法

どのように私はこのようなことをbashで行うことができますか?

if "`command` returns any error";
then
    echo "Returned an error"
else
    echo "Proceed..."
fi
337
Shinmaru

コマンドが成功または失敗した場合に条件付きで何かを行う方法

これが、bashのifステートメントが行うこととまったく同じです。

if command ; then
    echo "Command succeeded"
else
    echo "Command failed"
fi

コメントからの情報の追加:この場合、あなた[ ... ]構文を使用する必要はありません[はそれ自体がコマンドであり、testとほぼ同じです。これはおそらくifで使用する最も一般的なコマンドであり、シェルの構文の一部であると想定される可能性があります。ただし、コマンドが成功したかどうかをテストする場合は、上記のように、コマンド自体をifで直接使用します。

413
Keith Thompson

シェルコマンドが機能する場合に発生したい小さなことには、&&構文を使用できます。

rm -rf somedir && trace_output "Removed the directory"

同様に、Shellコマンドが失敗したときに発生する小さなことについては、||を使用できます。

rm -rf somedir || exit_on_error "Failed to remove the directory"

または両方

rm -rf somedir && trace_output "Removed the directory" || exit_on_error "Failed to remove the directory"

これらの構成要素を非常に多く使用することはおそらく賢明ではありませんが、制御のフローが非常に明確になる場合があります。

152
Bruce Ediger

最新のコマンド/関数の実行結果を含む$?の値を確認します。

#!/bin/bash

echo "this will work"
RESULT=$?
if [ $RESULT -eq 0 ]; then
  echo success
else
  echo failed
fi

if [ $RESULT == 0 ]; then
  echo success 2
else
  echo failed 2
fi
118
Ryan Stewart

これは私のために働きました:

command && echo "OK" || echo "NOK"

commandが成功した場合、echo "OK"が実行され、成功したため、そこで停止します。さもないと、 &&はスキップされ、echo "NOK"が実行されます。

52
German Rumm

注意すべきこと 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
6

私が思いつくことができる最もエラーが発生しやすいものは:

  • まず、値を取得します。次のようなことをするとします。

_RR=$?_

ここで、この状況だけでなく、直面する可能性のある他の状況についても検討してください。

定義された変数:

$ AA=1 ; if (( "10#0${AA}" == 1 )) ; then echo yes ; else echo no ; fi

回答:はい

$ AA=1 ; if (( "10#0${AA}" != 1 )) ; then echo yes ; else echo no ; fi

回答:いいえ

未定義の変数:

$ AA=1 ; if (( "10#0${BB}" == 1 )) ; then echo yes ; else echo no ; fi

回答:いいえ

$ AA=1 ; if (( "10#0${BB}" != 1 )) ; then echo yes ; else echo no ; fi

回答:はい

$ AA=1 ; if (( "10#0${BB}" == 0 )) ; then echo yes ; else echo no ; fi

回答:はい

これにより、すべての種類のオフエラーが防止されます。

あなたはおそらくすべての構文を知っていますが、ここにいくつかのヒントがあります:

  • 引用符を使用します。 _"blank"_がnothingになるのを避けます。
  • 変数の新しい現代表記は_${variable}_です。
  • 数字の前にゼロを連結して追加することで、「数字がまったくない」ことも回避できます。
  • ただし、ゼロを追加すると、数値は_base-8_になります。次のようなエラーが表示されます:
    • _7_を超える数値の場合はvalue too great for base (error token is "08")。そのときに_10#_が登場します:
    • _10#_は、数値を_base-10_に強制します。
4
Dr Beco

あなたはこれを行うことができます:

if ($( ping 4.4.4.4 -c1 > /dev/null )) ; then
  echo "ping response succsess!!!"
fi
1
Daniel
#!/bin/bash

if command-1 ; then
   echo "command-1 succeeded and now running from this block command-2"
   command-2
else
   echo "command-1 failed and now running from this block command-3"
   command-3
fi
1
Nick Vladiceanu

このスレッドの他の場所で述べたように、元の質問は基本的にそれ自体に答えます。以下は、if条件もネストできることを示す図です。

この例では、ifを使用して、ファイルが存在するかどうか、および通常のファイルかどうかを確認します。これらの条件に該当する場合は、サイズが0より大きいかどうかを確認してください。

#!/bin/bash

echo "Which error log are you checking today? "
read answer

if [ -f /opt/logs/$answer*.errors ]
    then
        if [ -s /opt/logs/$answer*.errors ]
            then
                echo "Content is present in the $answer error log file."
            else
                echo "No errors are present in the $answer error log file."
        fi
    else
        echo "$answer does not have an error log at this time."
fi
1
quartzinquartz