コマンドブロックと一緒にset -e(errexit)を使用し、ブロックが失敗した場合は別のコマンドを実行します(SC2181)。

コマンドブロックと一緒にset -e(errexit)を使用し、ブロックが失敗した場合は別のコマンドを実行します(SC2181)。

「(なし)多くのコマンドを実行し、ゼロ以外の終了コードでコマンドの1つを即座に停止するset -e方法」への回答を探していたので、今知りました。私が発見するまで、&&これset -eだけで十分でした。

(set -e; false; echo here) || echo error

hereしかし、error私は新しい問題に対する解決策をすぐに見つけました。

(set -e; false; echo here); [ $? -ne 0 ] && echo error

$?代わりに古い問題に直面しましたif cmdSC2181)。

今新しい質問がありました。 SC2181エラーを単に無視する必要がありますか、それとも動作させる適切な方法はありますか?

私も考えてみましたが、どんな信号が出るのかtrapわかりませんねset -e


気づく

if ! (set -e; false; echo here); then
  echo error
fi

また、.fromのhere代わりに印刷します。error住宅検査ウェブサイト:

冗長性に加えて、このパターンを避けるべき他の理由があります。

  • [...]
  • set -eakaを使用して実行または呼び出されたスクリプトは、errexit失敗を処理する句が後にあっても、コマンドが失敗するとすぐに終了します。

これはif、ステートメントが影響を受けないかerrexit無効になることを意味します。

また、欠落または置換()された場合、{}エラーチェックコマンドを含む次のコマンドの実行が停止します。


PS私は私のスクリプトでShellCheckエラーを最小限に抑えようとしています。これは、ほとんどの場合、スクリプトが最適化されていないかバグがあることを示します。さらに、追加の演算子を使用して多数のコマンド&&IMHOを実行すると、コードを読み取って編集するのが難しくなるため、(少なくともその特定のコマンドブロックについては)よりきれいな解決策を見つけたいと思います()

答え1

いつでも次のような不正行為を行うことができます。

last_block_failed() { return "$(( ! $? ))"; }
(set -o errexit
...
)
if last_block_failed; then
  echo>&2 error
fi

または同様の変形:

last_block_failed() (( ! $? ))
last_block_failed() { [ "$?" -ne 0 ]; }
last_block_failed() [[ $? -ne 0 ]]

Bash(Bourneシェルとすべてのコマンドを受け入れる他のほとんどのBourne様シェルとは異なり)では、関数本体は次のようになります。化合物コマンドなのでlast_block_failed() [ "$?" -ne 0 ]動作しません。コマンドグループ({ ...; }((...))[[ ... ]]その両方複合コマンド

関連情報