ターミナルバックスラッシュがない限り、heredocの出力を変数にキャプチャした後、heredocの改行文字は保持されます。
var=$(cat <<-EOF
a
b
c
EOF
)
echo "$var"
a
b
c
ただし、バックスラッシュ改行文字を保存しようとすると改行文字が失われます。
var=$(cat <<-EOF
a \\
b \\
c
EOF
)
echo "$var"
a \b \c
エスケープの追加にバックスラッシュを追加することは役に立ちません。
もちろん、サブシェルで実行されていない場合は、heredocを使用してバックスラッシュ改行文字で終わる行を生成できます。
$ cat <<-EOF
a \\
b \\
c
EOF
a \
b \
c
この問題を回避するには、改行文字を追加して変数変換を使用して目的の出力を生成できます。
var=$(cat <<-EOF
a \\@
b \\@
c
EOF
)
tr -d '@' <<<"$var"
a \
b \
c
サブシェルで実行されているheredocsでバックスラッシュの改行を維持するより直接的な方法はありますか?
ベストアンサー1
これがBashのバグなのか(またはバックスラッシュ改行動作が定義されていないのか)疑問に思います。私が試した他のすべてのシェルは、Bashとは異なる動作を表します。
$ cat nl.sh
echo "1:"
cat <<EOF
a \\
b \\
c
EOF
echo "2:"
var=$(cat <<-EOF
a \\
b \\
c
EOF
)
echo "$var"
出力:
$ bash nl.sh
1:
a \
b \
c
2:
a \b \c
そして
$ dash nl.sh
1:
a \
b \
c
2:
a \
b \
c
関数のコマンド置換にコードを入れることができます。これはパーサー関連の問題を解決するのに役立ちます。たとえば、次のようになります。
f() {
cat <<EOF
a \\
b
EOF
}
var=$(f)
echo "$var"