bash for 循环的意外字段扩展行为

bash for 循环的意外字段扩展行为

我在协调 linux/unix 中的所有字段扩展规则时遇到问题,所以我一直在进行试验。这是一个基于我的阅读的示例,该示例与我的预期不一致。

~$ IFS=$', \t\n'
~$ for i in 1 2 3; do echo num:"$i"; done
num:1
num:2
num:3
~$ myvar=1,2,3
~$ for i in $myvar; do echo num:"$i"; done
num:1
num:2
num:3
~$ for i in 1,2,3; do echo num:"$i"; done
num:1,2,3

最后的输出对我来说完全出乎意料。我在哪里可以找到字段扩展仅发生在变量的 bash for 循环中的规则?

在我看来,bash for 循环并没有遵循IFS我一开始设置的值。我误解了什么吗?

答案1

场分裂仅适用于未出现在双引号中的参数扩展、命令替换和算术扩展的结果,而不适用于文字字符串。

使用$myvar,您可以得到以下效果glob(split(1,2,3)): , split(1,2,3)with ,contains in IFSreturn 1, 2and 3, glob(1 2 3)return 1, 2and 3

文字字符串1,2,3不受该过程的影响,只是按原样返回。

答案2

执行这个命令:

LESS=+/'^ *IFS *The' man bash

阅读(“强调我的”):

IFS
用于分词的内部字段分隔符扩展后并使用 read 内置命令将行拆分为单词。默认值为`<space><tab><newline>'

这意味着如果不发生扩展,IFS 字段分割也不会发生。

嗯,实际上,拆分确实发生在原始行中,但具有固定的元字符集| & ; ( ) < > space tab

逗号,不是元字符,不用于分隔。

本书第七章有关命令行处理的更多详细信息:

  1. 将命令拆分为由固定元字符集分隔的标记:SPACE、TAB、NEWLINE、;、(、)、<、>、| 和 &。标记的类型包括单词、关键字、I/O 重定向器和分号。

  1. 获取由参数、命令和算术替换产生的行部分,并将它们再次拆分为单词。这次它使用 $IFS 中的字符作为分隔符,而不是步骤 1 中的元字符集。

相关内容