この効果を避ける

この効果を避ける

なぜシェル構造$(...)末尾の改行文字の削除

#!/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}"

おすすめ記事