我在协调 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 IFS
return 1
, 2
and 3
, glob(1 2 3)
return 1
, 2
and 3
。
文字字符串1,2,3
不受该过程的影响,只是按原样返回。
答案2
执行这个命令:
LESS=+/'^ *IFS *The' man bash
阅读(“强调我的”):
IFS
用于分词的内部字段分隔符扩展后并使用 read 内置命令将行拆分为单词。默认值为`<space><tab><newline>'
。
这意味着如果不发生扩展,IFS 字段分割也不会发生。
嗯,实际上,拆分确实发生在原始行中,但具有固定的元字符集| & ; ( ) < > space tab
逗号,不是元字符,不用于分隔。
这本书第七章有关命令行处理的更多详细信息:
- 将命令拆分为由固定元字符集分隔的标记:SPACE、TAB、NEWLINE、;、(、)、<、>、| 和 &。标记的类型包括单词、关键字、I/O 重定向器和分号。
- 获取由参数、命令和算术替换产生的行部分,并将它们再次拆分为单词。这次它使用 $IFS 中的字符作为分隔符,而不是步骤 1 中的元字符集。