了解IFS的默认值


10

在我的GNU bash版本4.2.8中,IFS默认具有空格,制表符和换行符的默认值:

usr@T42 ~ $ echo -n "$IFS" | hexdump -C
00000000  20 09 0a                                          | ..|
00000003
usr@T42 ~ $ 

有没有使用默认IFS的理由?另外,除了bash内置之外,哪些实用程序还使用IFS read

Answers:


13

每当shell执行称为单词拆分的任务时,都会使用IFS变量。使用此参数的最常见情况是在$var命令中进行参数扩展(例如)或命令替换(例如$(some-command)或不推荐使用的反引号)之后。在这里,如果扩展包含任何IFS字符,则在处理命令之前,它会分解为不同的“单词”。实际上,这意味着这些字符将替换的文本拆分为不同的参数(如果先指定了变量,则包括命令名称)。

因此,对于默认值的原因IFS是空格,制表符和换行符的是,这些是通常会被预期拆分字空格字符。

防止单词分裂的一种方法是在扩展("$var")周围使用双引号-实际上,您已经在问题中做到了这一点。如果您不这样做,将不会有输出,echo因为它将没有参数,只有字符会分割参数。

还要注意,在参数扩展后没有发生单词拆分的两个地方是变量赋值的(例如var=$othervarvar=$(somecommand)可以),并且在[[ ]]构造内([[ $var = $othervar ]]可以的但[ $var = $othervar ]应加引号)。

最后,正如一个智者曾经向我指出的那样,一个普遍的误解是防止分词是引用变量的唯一原因。并非如此,引号还可以防止路径名扩展glob扩展,这是众所周知的。如果变量包含类似这样的全局字符,*则当在命令中未使用该变量时,可以将这些字符扩展为文件名。例如,考虑:

var=*
echo $var

这将显示当前目录中的文件名。

正如Stephane在下面指出的那样展开时,其中的字符顺序IFS很重要"$*"。从bash手册页:

"$*" is equivalent to "$1c$2c...", where c is the first character of the value of
the IFS variable.  If IFS is unset, the parameters are separated by spaces.  If
IFS is null, the parameters are joined without intervening separators.

有关分词的更多示例,请参见以下答案-https: //unix.stackexchange.com/a/118444/48083


1
$IFS还使用的第一个字符,"$*"这就是顺序重要的原因。
斯特凡Chazelas

2
另请注意,zsh默认情况下包括NUL字符$IFS(其他外壳程序不支持在其变量中保留NUL字符)。
斯特凡Chazelas
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.