将 IFS 设置为 null 时不会忽略前导空格序列

将 IFS 设置为 null 时不会忽略前导空格序列

根据手册:

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 sssssssssssssssXYZprint XYZsssssssssssssssXYZ不是s空格字符

是不是因为这只影响参数扩展、命令扩展、算术扩展的结果?

如果是这样,那么为什么 echo 不打印前导空格字符?

答案1

有很多原因。

首先,分词仅发生且IFS仅适用于扩展结果,而不是直接应用于命令行上的文本 (*)。将命令行拆分为单词是不同的,连续的不带引号的空格与那里的空格相同。在somecmd foo:bar,中somecmd获取一个参数,而在 , 中somecmd foo bar,无论是否IFS包含冒号或空格,它都会获取两个参数。在 中echo xyzecho得到单个参数xyz

其次,IFS在命令行开始解析之前设置的值很重要。如果我们设置var=foo:bar然后运行IFS=: printf "%s\n" $varprintf仍然会得到格式字符串后面的参数,并且输出foo:bar在一行上。同一命令上的变量设置仅适用于该命令内,里面它,或者printfecho使用IFS.

我们必须设置IFS一个较早的命令来应用它,例如这将在两个单独的行上打印foo和: 。这将保留空格:。barvar=foo:bar IFS=:; printf "%s\n" $varvar=" foo" IFS=:; printf "%s\n" $var

不过,在很多情况下,最好只引用扩展,因为这将保护结果免受分词的影响通配符,无论 的值如何IFS

(* AFAIK 在一些早期的 shell 中IFS确实适用于直接在命令行上的单词。设置IFS=b将使echo foobarprint foo ar。)

相关内容