★追記があります。
クラウド時代なので,JSONを環境変数に入れて渡したいということがあると思います。そしてそれをファイルに保存したいということがあると思います。
こういうJSONがあるとします。
$ FOO='{"foo":"b\na\nr"}'
アプリケーションの都合でFOO
をファイルに保存しないといけない!あなたはちゃんとできますか?
$ echo $FOO > foo.txt $ cat foo.txt {"foo":"b a r"}
〜完〜: あなたはJSONのパースに失敗する。
おさらい
- シェルは変数のスペースを展開してくれる
FOO="a b c"
のとき・・・"$FOO"
と書くとスペースは展開されず1つの引数扱いになる$FOO
と書くとスペースが展開され,3つの引数扱いになる
これはまあみんな知ってると思うし,今回の本筋ではないです。
ところで・・・
- シェルはエスケープシーケンスを展開する
これ困るの?ということがあるとおもいますが,たまに困ります。
- 具体的にはFirebaseをECSで使う場合!!
- コンテナに含めたくないのでGCPの鍵JSONがAWS Secret Managerを経由して渡ってくる
- Firebaseの
$GOOGLE_APPLIACTION_CREDENTIALS
はファイル名しか受け付けないので,ECS側でいったんファイルに落とすということをする必要がある - 鍵の文字列リテラルに
\n
が入っている!!
こういうのが環境変数に入っていると困るわけです。勝手に\n
が展開されてしまう。これはいけない。
perl使う
シェルスクリプトでやるのは諦めてperlを使いました。
perl -e 'print $ENV{JSON_STRING_CONTAINING_ESCAPE_SEQUENCE}' > foo.txt
困ったらperl,覚えておきましょう。
追記
シェルスクリプトで環境変数の中身を壊すことなくファイルに保存する - Lambdaカクテルb.hatena.ne.jp「困ったらperl」これはひどい。筆者がechoの動作をよく知らないだけ。この場合はprintfコマンドを使うべき。Perlを使えというなら最初からPerlを語ればよく、わざわざシェルスクリプトに言及することには悪意すら感じる。
2020/01/10 15:07
悪意はありませんが,printf "%s" $FOO
でも同じことが可能でした。ご指摘ありがとうございました。perlではシェルによる互換性の問題が起こりにくいことから,自分はよく使っています。