回答:
簡単な答えは、kshがそのように書かれている(そしてbashに互換性がある)ためです。しかし、その設計の選択には理由があります。
ほとんどのコマンドはテキスト入力を想定しています。UNIXの世界では、テキストファイルは一連の行で構成され、各行は改行で終わります。そのため、ほとんどの場合、最後の改行が必要です。特に一般的なケースは、コマンドの中断を伴うコマンドの出力を取得し、何らかの方法で処理してから、別のコマンドに渡すことです。コマンド置換は、最後の改行を取り除きます。<<<
1つ戻します。
tmp=$(foo)
tmp=${tmp//hello/world}
tmp=${tmp#prefix}
bar <<<$tmp
とにかくBashとkshはバイナリデータを操作できない(null文字に対応できない)ので、それらの機能がテキストデータ向けに調整されていることは驚くことではありません。
<<<
ここでは、文字列の構文は次のように、とにかく便宜上ほとんどです<<
ヒアドキュメント。最終的な改行を追加しない場合は、echo -n
(bashで)またはprintf
パイプラインを使用します。
<<<
によってボーンの世界に紹介されたのzsh
ではないksh
。そして、それはのUnixのポートで同様の作業に触発されたrc
なかったではない、余分な改行文字を追加します。興味深いことに、=(<<<text)
演算子はその改行をに追加しませんzsh
。
printf
末尾の改行を回避しながら、here-stringを(他のユーティリティなどを使用せずに)記述する方法はありますbash
か?@StéphaneChazelasが指摘したように、で可能ですzsh
。
here-stringsに改行を追加することが実用的なシナリオの1つはread
、set -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'
これが、ここにある文字列の最後に改行を入れる唯一の方法だと思います:
xxd <<<`echo -ne "a\n"`
here-string演算子は、送信した構文で改行が指定されていない限り、改行を削除するように見えます。
xxd <<<$(echo a)
ます。