63525


APIの JSON レスポンスが特定の値であることをバリデーションするシェルスクリプトを書いているところなのですが不思議な現象に遭遇しました

curl の結果の代用として echo で生成した JSON レスポンスに対して  
キー x の中身が "x" という文字列  
キー y の中身が "y" という文字列  
キー z の中身が "z" という文字列  
であることをチェックするテストスクリプトを以下のように書きました

[code]

    X=$(echo '{"x":"x","y":"y","z":"z"}' | jq -r '.x,.y,.z')
    Y=$(echo 'x y z')
    echo $X
    echo $Y
    if [ "$X" != "$Y" ]; then echo 'failed'; exit; fi
    
[/code]

これを動かしたところ

[code]

    x y z
    x y z
    failed
    
[/code]

という結果になったのです

比較の直前でデバッグ出力してみると全く同じ出力にもかかわらず結果が failed (文字列不一致の分岐) になります

何故なのでしょうか


CC BY-SA 4.0
2020-03-03T10:20:41.817
63523
2020-03-05T05:28:37.380
2020-03-04T08:45:52.557
question
bash jq
bash でJSON の値が特定の値であるかチェックしたい


クォートを入れ、

[code]

    echo "$X"
    echo "$Y"
    
[/code]

にして試してみてください。

jq の出力した `$X` はスペース区切り 1 行の文字列ではなく、改行区切り 3 行の文字列です。`echo $X` だと `echo` に 3
つの引数が与えられたとみなされてそれらがスペース区切りで出力されますが、`echo "$X"` だと 1 つの引数が与えられるだけで、`$X`
の中身がそのまま出力されます。

スペース区切り 1 行の文字列として出力するには、`jq` の `join`
を使うと良さそうです。ただし値にスペースが含まれる場合それが区別できなくなるので気をつけてください。

[code]

    echo '{"x":"x","y":"y","z":"z"}' | jq -r '[.x,.y,.z]|join(" ")'
    
[/code]


CC BY-SA 4.0
2020-03-03T11:02:08.170
63525
2020-03-05T05:28:37.380
2020-03-05T05:28:37.380
19110
19110
63523
answer


`$X` の方は **3つの要素** を抜き出している一方、

[code]

    $ echo '{"x":"x","y":"y","z":"z"}' | jq -r '.x,.y,.z'
    x
    y
    z
    
[/code]

`$Y = 'x y z'` はシングルクォーテーションを使用しているので3つの要素ではなく、 **ひと塊の文字列**
とみなされて比較結果が意図した通りになっていないのだと思います。


CC BY-SA 4.0
2020-03-03T11:10:55.660
63526
2020-03-03T11:10:55.660
3060
63523
answer