&&式の左側で呼び出された関数内でエラーが発生し、失敗しました。

&&式の左側で呼び出された関数内でエラーが発生し、失敗しました。

私はいくつかの機能を持つBashスクリプトを書いています。そのコードを明示的に処理するコンテキスト(条件付きifまたは||代替の前など)を除いて、コマンドがゼロ以外の終了コードを返す場合は、スクリプトを終了したいと思います。これをより簡単にするために、スクリプトからすべてのサブシェルの使用を削除し、見つけることができるすべてのエラー処理オプションを有効にしました。

残念ながら、私はまだエラーが抑制される一般的なパターンに触れています。

関数のコマンドがゼロ以外の終了コードを返しますが、関数の最後のコマンドではなく、関数が式の最初の部分として呼び出される場合、終了&&コードは無視されます。

#!/bin/bash

trap 'echo "Error occurred." && exit' ERR
set -o errexit;  # -e
set -o errtrace; # -E
set -o pipefail;

first-step-fails() {
    # These should be redundant, but are repeated to be certain and clear.
    trap 'echo "Error occurred." && exit' ERR
    set -o errexit;  # -e
    set -o errtrace; # -E
    set -o pipefail;

    false; # exit code 1 (failure)
    true;  # exit code 0 (success)

    echo "A is executed.";
}

first-step-fails && echo "B is executed.";
A is executed.
B is executed.

echo電話することは知りませんでしたfalse


&&式で関数が呼び出されないと、エラーが発生します。

#!/bin/bash

trap 'echo "Error occurred." && exit' ERR
set -o errexit;  # -e
set -o errtrace; # -E
set -o pipefail;

first-step-fails() {
    # These should be redundant, but are repeated to be certain and clear.
    trap 'echo "Error occurred." && exit' ERR
    set -o errexit;  # -e
    set -o errtrace; # -E
    set -o pipefail;

    false; # exit code 1 (failure)
    true;  # exit code 0 (success)
    echo "A is executed.";
}

first-step-fails ### && echo "B is executed.";
Error occurred.

失敗が関数の最後のステップである場合、エラーはキャッチされませんが、関数はもちろんゼロ以外の終了状態を渡し、外部echo

#!/bin/bash

trap 'echo "Error occurred." && exit' ERR
set -o errexit;  # -e
set -o errtrace; # -E
set -o pipefail;

first-step-fails() {
    # These should be redundant, but are repeated to be certain and clear.
    trap 'echo "Error occurred." && exit' ERR
    set -o errexit;  # -e
    set -o errtrace; # -E
    set -o pipefail;

    false; # exit code 1 (failure)
    ### true;  # exit code 0 (success)
    ### echo "A is executed.";
}

first-step-fails && echo "B is executed.";
(no output)

式の左側で呼び出された関数内で呼び出されたコマンドがゼロ以外の終了状態を返したときにbashスクリプトを終了するにはどうすればよいですか&&

私はmacOS(GNU Bash 4.4.23組み込み)でテストしてきましたが、Alpine Linux(GNU Bash 4.4.19パッケージ)でも動作するソリューションが必要です。

ベストアンサー1

私にとっては、次の説明のように見えますset -e

失敗したコマンドがコマンドの一部である場合、シェルはリストを終了しません... &&または||内で実行されます。

関数呼び出しにすべてのコマンドを含めるには、「リストの&&部分」を自由に解釈してください。したがって、関数内で単純な失敗したコマンドでも、&&チェーンから呼び出されたときにERRトラップをトリガーしません。

関数コマンドの1つが失敗したときに関数のコマンドの実行を停止する必要がある場合、1つの方法はそのコマンドをすべてブロックにリンクすることです。

first-step-fails() {
    { 
      true &&
      false &&
      true;
    } || exit 1

    echo "A is executed.";
}

first-step-fails && echo "B is executed.";

...結果は出力されず、戻りコードは1です。

おすすめ記事