はじめに:関連性のある質問を見てみました。「ls」と「echo $(ls)」の違い
bashは出力キャプチャ時にトークン化を実行しますか?このガイド - mywiki.wooledge.org/WordSplittingは「いいえ」と言います:
タスクの拡張はトークン化を実行しません。したがって、次のようにコマンドに何も引用する必要はありません。 [...]
bar=$(a command)
ただし、出力を行うとres=$(find); echo $res
次のようになりますfind
。
$ find
.
./file2
./file1
./test.sh
$ res="$(find)"; echo $res
. ./file2 ./file1 ./test.sh
$ res=$(find); echo $res
. ./file2 ./file1 ./test.sh
答え1
引用したテキストは変数の割り当てにのみ関連していることに注意してくださいres
。この部分に問題はありません。
find
示されているように、ユーティリティは改行で区切られたパス名を出力として生成します。
この出力を変数に割り当てると、改行は保持されます(削除された最後の行を除く)。
これまでは大丈夫でしたが、その後は...
echo
で引用符なしの変数を使用して呼び出すと、bash
変数の値は空白、タブ、および改行(デフォルト)に分割され、結果の文字列はファイル名として生成されます(globbed)。結果の単語は別の引数として提供されますecho
。
ユーティリティecho
は空白文字で区切られた引数を出力します(末尾に改行が追加されます)。これがあなたが示した状況ですecho $res
。
シェルが変数を単語とファイル名に分割せずに変数の値を表示するには、変数の拡張子を二重引用符で囲むかを検討しますecho "$res"
(printf '%s\n' "$res"
参照)。なぜprintfがechoより優れているのですか?)。
つまり、呼び出し時に変数拡張をecho
引用する必要があります。