条件にコマンドを含める必要がありますか、それとも戻りコードをテストする必要がありますか?

条件にコマンドを含める必要がありますか、それとも戻りコードをテストする必要がありますか?

これはベストプラクティスに関する簡単な質問です。どちらを使うべきですか?

オプション1

ping -c1 "$host"

if [[ $? -eq 0 ]] ; then
   command
else
   command
fi

オプション2

if ping -c1 "$host" ; then
   command
else
   command
fi

簡単な命令であることはわかりますが、大きくなると違いが途方もないことがあります。

答え1

優先事項ですが、1つを追加する予定の場合は、2番目のフォームがより安全になりますset -e。このフォームはまだ期待どおりに機能しますが、最初のフォームでは失敗した場合、スクリプトはすぐに終了しますping(ゼロ以外の値で)。終了ステータスを返します)。

注: 演算子は-eq、ではありませんeq

答え2

オプション2は、成功と失敗の違いにのみ興味がある場合にのみ選択できるオプションです。ゼロ以外のさまざまな終了状態を区別する必要がある場合は、オプション1が必要です。

some-command arg1 arg2
exit_status=$?
if [[ $exit_status -eq 0 ]]; then
   # ...
elif [[ $exit_status -eq 1 ]]; then
   # ...
elif [[ $exit status -eq 42 ]]; then
   # ...
else
   # ...
fi

(最初のコマンドによってリセットされるため、別の名前$?で保存する必要があります。失敗した場合、最初のコマンドは同じ値を再テストしません。)exit_status$?[[ ... ]]elif$?

まあ、必ずしもそうではありません。必要。 3番目のオプションはステートメントを使用することです。この場合、その値を再参照する必要がない場合はcase保存する必要はありません。$?

some-command arg1 arg2
case $? in
   0) # ...
   ;;
   1) # ...
   ;;
   42) # ...
   ;;
   *) # ...
   ;;
 esac

答え3

理解しにくいようですが、実際には一般的に使用されている次のBashイディオムを使用できます。

ping -c1 "$host" && command_success || command_failure

関連情報