web-dev-qa-db-ja.com

コマンド置換から末尾の改行文字はどこに移動しましたか?

次のコードは、状況を最もよく表しています。最後の行が末尾の改行文字を出力しないのはなぜですか?各行の出力はコメントに示されています。私は使用していますGNU bash、バージョン4.1.5

     echo -n $'a\nb\n'                  | xxd -p  # 610a620a  
           x=$'a\nb\n'   ; echo -n "$x" | xxd -p  # 610a620a
     echo -ne "a\nb\n"                  | xxd -p  # 610a620a
x="$(echo -ne "a\nb\n")" ; echo -n "$x" | xxd -p  # 610a62
15
Peter.O

コマンド置換関数$()(およびその従兄弟のバッククォート)は、特に末尾の改行を削除します。これは 文書化された動作 であり、構成を使用するときは常に注意する必要があります。

テキスト本文内の改行は置換演算子によって削除されませんが、シェルで単語分割を行うときにも削除される可能性があるため、引用符を使用したかどうかによって結果が異なります。これら2つの使用法の違いに注意してください。

$ echo -n "$(echo -n 'a\nb')"
a
b

$ !! | xxd -p
610a62

$ echo -n  $(echo -n 'a\nb')
a b

$ !! | xxd -p   
612062

2番目の例では、出力は引用符で囲まれず、改行はWord分割として解釈され、出力にスペースとして表示されます。

18
Caleb

コマンド置換を使用する場合、シェルはサブシェルでコマンドを実行し、それらのstdoutを返します。このプロセスでは、表彰がプレーンな分割単語を返すため、IFS文字はその重要性を失います(引用符で囲まれていない場合)。そのため、末尾の文字は削除されます。例えば:

_$ echo "$(echo -e '\n')" | wc
 1       0       1

$ echo -e '\n' | wc
2       0       2
_

より実際的には、ディレクトリ名の間に改行があってもpwdは機能しますが、$(pwd)は機能しません。

通常の回避策は、コマンドの最後に何かを追加し、その後それを削除することです。

6
Philomath