Bash でコマンド置換+ヒアドキュメントを使った際に「warning: command substitution: 1 unterminated here-document」が発生した場合の対策です。
この警告は、ヒアドキュメント全体もコマンド置換内(のサブシェル内)に記述することで回避できます。
VAL1="Any Value"
RESULT=$(cat << _EndOfJson_
{
"foobar1": "${VAL1}"
}
_EndOfJson_
)
echo "$RESULT"
#=> {
#=> "foobar1": "Any Value"
#=> }
VAL1="Any Value"
RESULT=$(cat << _EndOfJson_
{
"foobar1": "${VAL1}"
}
_EndOfJson_
)
#=> {
#=> "foobar1": "Any Value"
#=> }
解説
やりがちなのが以下のような記述です。
VAL1="Any Value"
RESULT=$(cat << _EndOfJson_)
{
"foobar1": "${VAL1}"
}
_EndOfJson_
#=> warning: command substitution: 1 unterminated here-document が発生
# ちなみに、コマンド自体はなんとなく実行される
ほとんど似ていますが、コマンド置換 $()
のカッコの位置が異なることがポイントです。
$(cat << _EndOfJson_)
は、サブシェル(子プロセス)で実行されます。しかし、このカッコ内 _EndOfJson_
という終端行がありません。これが warning の発生理由です。
こういったこともあり、手で1行づつ入力すると $(cat << _EndOfJson_)
という行の時点で warning が発生します。
※ しかし、warning が出てもなんとなく動いちゃう(理由は追ってない)ので、困りもの...
対策の方は、$RESULT
視点では RESULT=$(...)
となっており、$(...)
内にヒアドキュメントの終端が含まれているため、警告が出ないのです。
あとがき
GPT-4o モデルに curl コマンドで画像をプロンプトとして送信する方法を書いてたら、ほとんどシェル芸の話だったことに気が付いたので、分割しました。
EoT