根据手册:
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
print
XYZ
而sssssssssssssssXYZ
不是s
空格字符
是不是因为这只影响参数扩展、命令扩展、算术扩展的结果?
如果是这样,那么为什么 echo 不打印前导空格字符?
答案1
有很多原因。
首先,分词仅发生且IFS
仅适用于扩展结果,而不是直接应用于命令行上的文本 (*)。将命令行拆分为单词是不同的,连续的不带引号的空格与那里的空格相同。在somecmd foo:bar
,中somecmd
获取一个参数,而在 , 中somecmd foo bar
,无论是否IFS
包含冒号或空格,它都会获取两个参数。在 中echo xyz
,echo
得到单个参数xyz
。
其次,IFS
在命令行开始解析之前设置的值很重要。如果我们设置var=foo:bar
然后运行IFS=: printf "%s\n" $var
,printf
仍然会得到一格式字符串后面的参数,并且输出foo:bar
在一行上。同一命令上的变量设置仅适用于该命令内,里面它,或者printf
不echo
使用IFS
.
我们必须设置IFS
一个较早的命令来应用它,例如这将在两个单独的行上打印foo
和: 。这将保留空格:。bar
var=foo:bar IFS=:; printf "%s\n" $var
var=" foo" IFS=:; printf "%s\n" $var
不过,在很多情况下,最好只引用扩展,因为这将保护结果免受分词的影响和通配符,无论 的值如何IFS
。
(* AFAIK 在一些早期的 shell 中IFS
确实适用于直接在命令行上的单词。设置IFS=b
将使echo foobar
print foo ar
。)