POSIX 字段拆分和双引号行为,带有 `echo` 和 `for`

jII*_*jII 0 shell scripting posix

根据字段拆分双引号for 循环的 POSIX 标准以及以下示例,我无法理解为什么echo "$s"在数字之间使用双引号显示新行,而在数字之间使用双引号for x in "$s"不显示新行. 有人可以澄清一下吗?

$ s=$(seq 1 4)
$ echo $s
1 2 3 4
$ echo "$s"
1
2
3
4
$ for x in $s; do echo $x; done
1
2
3
4
$ for x in "$s"; do echo $x; done
1 2 3 4
Run Code Online (Sandbox Code Playgroud)

小智 7

正如您正确提到的,IFS(字段拆分)环境变量在这里起着重要作用。通常情况下,IFS被设置为包括<space><tab><newline>字符。这意味着当变量上没有使用引号时,shell 解释器将IFS尽可能按值将其分解为单独的参数(它甚至会压缩多个IFS字符)。

因此,在您的s变量中,始终存在以下值。其余的取决于解释。

1<newline>2<newline>3<newline>4
Run Code Online (Sandbox Code Playgroud)

在第一个中for,shell$s在运行之前分裂for并执行四次循环。对于以下内容echo,没有任何额外的拆分,因此每个元素都打印在一行上(这是这样echo做的)。

如上所述,第二个for将仅针对整个s值运行一次。现在发生的事情是,shell在传递到之前打破了s变量(因为没有双引号)。这意味着字符将变得无关紧要,每个数字只是一个参数。当获取多个参数时,它会以空格字符分隔的相同顺序打印它们。IFSechox<newline>echo