bash "catch block"は間違ったサブシェルをキャプチャしません。

bash

だから私はこれを持っています:

  (
        set -eo pipefail;
         {
          set -eo pipefail;
        file_path="$(echo "$i" | jq -r '.file_path')"

         if [[ -n "$file_path" ]]; then
              echo "$i" > "$file_path";
          fi
        } || {
           # never seems to reach here
           echo "!!! json parse error: 'xxxx'";
        }
     )

私の端末では、次のようなものが欲しい。

!!! json parse error: 'xxxx'

jqところで、端末でこのようなエラーが発生し続けます。

parse error: Invalid numeric literal at line 2, column 0

私にとって一般的に動作する「catchブロック」がここで動作しない理由はわかりません。

ベストアンサー1

のシェルpipefailオプションは、bashパイプの終了状態がゼロ以外の終了状態(またはすべてのコマンドが正常に終了した場合は0)を持つ最も右側のコマンドの終了状態になるようにします。あなたの場合、唯一のパイプはecho+jqパイプであり、echo失敗する可能性がないため、そのpipefailオプションは重複します。

errexit()シェルオプションを使用するset -eと、ゼロ以外の終了ステータスを返す最初のコマンドでシェルが終了します。〜しない限りこのコマンドは、コード内のものと同じAND-ORリストの一部です。

!!! json parse error: 'xxxx'コード出力をトリガーする唯一の方法は、シェルが書き込めifない場合にゼロ以外の終了状態を返す複合コマンドを使用することです$file_path

個人的に、私はこれらの2つのシェルオプションが絶対に必要な状況でなければ避けたいと思います(私のシェルスクリプトではこれらの状況の1つを見たことがありません)。


jq解析でnull以外の値が生成された場合は、JSONドキュメントをファイル(の出力から提供)に書き込み、解析に失敗した場合はエラーメッセージを出力したいようです。

おそらく構文解析がうまくいったことを確認する最も簡単な方法は、ステートメントjqで直接終了状態を使用することです。if

ここでは、エラー出力をさらにキャプチャしてjq独自のエラー報告に使用します。

if filepath=$( jq -r '.file_path' <<<"$json_document" 2>&1 )
then
    # Parsing went ok.
    if [ -n "$filepath" ]; then
        # "$filepath" is non-empty.
        printf '%s\n' "$json_document" >"$filepath"
    fi
else
    # Parsing failed.
    printf 'ERROR: "%s"\n' "$filepath" >&2
fi

jqしかし、正直に言うと、まったく介入せずに独自のエラー報告を実行することでコードを簡素化しました。

if filepath=$( jq -r '.file_path' <<<"$json_document" ) && [ -n "$filepath" ]
then
    # Parsing went ok, and "$filepath" is non-empty.
    printf '%s\n' "$json_document" >"$filepath"
fi

またはjq、値が空であると仮定すると、テストは削除されます-n

if filepath=$( jq -r -e '.file_path' <<<"$json_document" )
then
    # Parsing went ok, and "$filepath" is non-empty (and not null or false).
    printf '%s\n' "$json_document" >"$filepath"
fi

の場合、-eエラーjqが発生したときにゼロ以外の終了状態が返されますが(通常のように)、最終式で空の結果が生成された場合、またはnull返されますfalse

おすすめ記事