here-stringのbashが末尾の改行文字を追加するのはなぜですか?


34

次の例は、改行がhere-stringに追加されることを示しています。
なぜこれが行われるのですか?

xxd -p <<<'a'  
# output: 610a

xxd -p <<<'a
'
# output: 610a0a

回答:


38

簡単な答えは、kshがそのように書かれている(そしてbashに互換性がある)ためです。しかし、その設計の選択には理由があります。

ほとんどのコマンドはテキスト入力を想定しています。UNIXの世界では、テキストファイルは一連の行で構成され、各行は改行で終わります。そのため、ほとんどの場合、最後の改行が必要です。特に一般的なケースは、コマンドの中断を伴うコマンドの出力を取得し、何らかの方法で処理してから、別のコマンドに渡すことです。コマンド置換は、最後の改行を取り除きます。<<<1つ戻します。

tmp=$(foo)
tmp=${tmp//hello/world}
tmp=${tmp#prefix}
bar <<<$tmp

とにかくBashとkshはバイナリデータを操作できない(null文字に対応できない)ので、それらの機能がテキストデータ向けに調整されていることは驚くことではありません。

<<<ここでは、文字列の構文は次のように、とにかく便宜上ほとんどです<<ヒアドキュメント。最終的な改行を追加しない場合は、echo -n(bashで)またはprintfパイプラインを使用します。


私の答えよりもずっと徹底しています。
マイク

2
bashはksh93からhere-stringsを借りたかもしれませんが、kshはzshから順番に借りて、Plan 9シェルrcから取得しました。
マークリード14年

2
<<<によってボーンの世界に紹介されたのzshではないksh。そして、それはのUnixのポートで同様の作業に触発されたrcなかったではない、余分な改行文字を追加します。興味深いことに、=(<<<text)演算子はその改行をに追加しませんzsh
ステファンシャゼル

あなたがこの答えに興味があるのか​​疑問に思うなら、SOこの質問のためです。
fedorqui

1
printf末尾の改行を回避しながら、here-stringを(他のユーティリティなどを使用せずに)記述する方法はありますbashか?@StéphaneChazelasが指摘したように、で可能ですzsh
CTodea

3

here-stringsに改行を追加することが実用的なシナリオの1つはreadset -eモードがアクティブなときにコマンドを使用する場合です。set -eスクリプトがゼロ以外のステータスコードを生成するステートメントに(多少なりとも)遭遇すると、スクリプトが終了することを思い出してください。read改行なしの文字列を検出すると、ゼロ以外のステータスコードを生成することを考慮してください。

#!/bin/bash
set -e

# The following statement succeeds because here-strings append a newline:
IFS='' read -r <<< 'newline appended'
echo 'Made it here'

# The following statement fails because 'read' returns a non-zero status
# code when no newlines are encountered.
printf 'no newline' | IFS='' read -r
echo 'Did not make it here'

-3

これが、ここにある文字列の最後に改行を入れる唯一の方法だと思います:

xxd <<<`echo -ne "a\n"`

here-string演算子は、送信した構文で改行が指定されていない限り、改行を削除するように見えます。


4
最後の改行を削除するのはコマンド置換です。これを単純化できxxd <<<$(echo a)ます。
ジル「SO-悪であるのをやめる」
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.