マニュアルによると:
If IFS is unset, or its value
is exactly <space><tab><newline>, the default, then sequences of
<space>, <tab>, and <newline> at the beginning and end of the
results of the previous expansions are ignored, and any sequence
of IFS characters not at the beginning or end serves to delimit
words.
そして:
If
the value of IFS is null, no word splitting occurs.
ここで得られたのは、IFSが空の場合、トークン化が発生しないため、一連の先行スペース、タブ、および改行が無視されないことです。
このステートメントが正しい場合は、なぜ空白文字の代わりにIFS= echo sssssssssssssssXYZ
印刷するのですか?XYZ
sssssssssssssssXYZ
s
パラメータ拡張、命令拡張、算術拡張結果にのみ影響を及ぼすためですか?
それでは、なぜ先行する空白文字をエコー印刷しないのですか?
答え1
多くの理由。
まず、トークン化はIFS
コマンドライン(*)のテキストに直接適用されず、拡張結果にのみ適用されます。コマンドラインを単語に分割することは異なり、引用符のない連続したスペースはそこにあるスペースと同じです。では1つのパラメータを取得somecmd foo:bar
しsomecmd
ますが、コロンまたはスペースを含めるsomecmd foo bar
かどうかにかかわらず、IFS
2つのパラメータを取得します。では単一のパラメータを取得echo xyz
します。echo
xyz
次に、IFS
コマンドラインで解析を開始する前に設定した値が重要です。設定var=foo:bar
して実行すると、まだ次のようになりますIFS=: printf "%s\n" $var
。printf
一つフォーマット文字列に従い、foo:bar
1行に出力されるパラメータ。同じコマンドの変数設定は、そのコマンド内でのみ適用されます。~へそれを使用または使用printf
しません。echo
IFS
これを適用するには、前のコマンドを設定する必要がありますIFS
。たとえば、これにより、2つの別々の行に合計が印刷されますfoo
。これによりスペースが保存されます。bar
var=foo:bar IFS=:; printf "%s\n" $var
var=" foo" IFS=:; printf "%s\n" $var
しかし、ほとんどの場合、拡張子を引用する方が良いでしょう。これにより、トークン化から結果が保護されます。そして値に関係なくワイルドカードですIFS
。
(* AFAIK一部の初期シェルでは、IFS
コマンドラインから直接単語に対して機能しました。これを設定するとprintIFS=b
になります。)echo foobar
foo ar