なぜシェル構造$(...)
末尾の改行文字の削除?
#!/bin/bash
S='a
b
'
printf '%i [%s]\n' "${#S}" "$S"
T=$(printf '%s' "$S")
printf '%i [%s]\n' "${#T}" "$T"
これを印刷してください:
4 [a
b
]
3 [a
b]
この変数S
には2つの改行文字が含まれています。最初はprintf
正しく印刷されます。次に、2番目は、評価を使用して正確に同じ結果をprintf
印刷して割り当てます。S
最後の3番目のショーT
$(...)
printf
最後の改行文字がありませんT
!なぜ?
sh、ksh、Zshを使用して同じ結果を得ました。
ベストアンサー1
これは文書化された動作ですman bash
。
Bash はサブシェル環境でコマンドを実行し、コマンド置換をコマンドの標準出力に置き換え、末尾の改行を削除して拡張を実行します。
もちろん、「なぜ?」という質問に対する答えではないと言うこともできます。
正式な説明はわかりません。私の考えでは、これは一般的に必要なものなので、これは意味があると思います。改行文字を削除するよりも追加する方が簡単です。
# This is how people are used to print text
echo foo
# In the other scenario this would end in two newlines at the end
echo foo "$(whatever)"
# could behandled with echo -n or printf but who would consider that an improvement?
もう一つの理由は、いくつかのコマンドは末尾に改行文字を追加しますが、他のコマンドはそうではないからです。この動作は、ユーザーがこの違いを気にする必要がある負担を軽減します。
この効果を避ける
実際のコマンド出力を取得するには、次のようにします。
T=$(whatever; echo x)
T_real="${T%x}"