我正在运行Bash版本4.2.25。这是我的代码:
#!/usr/bin/env bash
string="one:two:three:four"
# without quotes
IFS=: read -ra array_1 <<< $string
for i in "${array_1[@]}"; do printf "i = [$i]\n"; done
# output:
# i = [one two three four]
# with quotes
IFS=: read -ra array_2 <<< "$string"
for i in "${array_2[@]}"; do printf "i = [$i]\n"; done
# output:
# i = [one]
# i = [two]
# i = [three]
# i = [four]
解释行为差异的原因是什么?
答案 0 :(得分:3)
我无法使用bash 4.2.46和bash 4.3.30在Linux上重现您的问题。但是,这里的改编版本确实显示了所描述的行为:
string="one:two:three:four"
IFS=:
read -ra array_1 <<< $string
for i in "${array_1[@]}"; do printf "i = [$i]\n"; done
# i = [one two three four]
read -ra array_2 <<< "$string"
for i in "${array_2[@]}"; do printf "i = [$i]\n"; done
# i = [one]
# i = [two]
# i = [three]
# i = [four]
这是因为变量实际上没有在空格上拆分,它们会在$IFS
上拆分(默认为空格,制表符和换行符)。
由于我们已经覆盖了$IFS
,因此我们必须谨慎引用冒号。空间不再重要。
源代码显示string_list
中的Bash hardcodes a space,通过write_here_string调用。当IFS
不包含空格时,扩展为多个单词的字符串将不再read
成为类似行的标记,从而使差异更明显。
PS:这是一个很好的例子,说明为什么我们应该总是引用我们的变量,即使我们知道它们包含什么。
答案 1 :(得分:1)