我想将一个字符串分成两个变量(而不必使用while循环):
var="hello:world"
IFS=':' read var1 var2 <<< $var
echo "var1: $var1"
echo "var2: $var2"
但我没有得到期望的结果:
var1: 'hello world'
var2: ''
请问是否有可能用这种方式(或类似的方式)来完成?
我想将一个字符串分成两个变量(而不必使用while循环):
var="hello:world"
IFS=':' read var1 var2 <<< $var
echo "var1: $var1"
echo "var2: $var2"
但我没有得到期望的结果:
var1: 'hello world'
var2: ''
请问是否有可能用这种方式(或类似的方式)来完成?
这与引号有关。使用:
IFS=':' read var1 var2 <<< "$var"
^ ^
代替
IFS=':' read var1 var2 <<< $var
查看结果:
$ IFS=':' read var1 var2 <<< "$var"
$ echo "var1=$var1, var2=$var2"
var1=hello, var2=world
但是
$ IFS=':' read var1 var2 <<< $var
$ echo "var1=$var1, var2=$var2"
var1=hello world, var2=
IFS=':' read var1 var2 <<< hello:bye
,那么它会被正确分割,而如果它来自一个变量,它就不会。 - fedorqui... <<< "$var"
)也可以工作。 - chepner<<< EOF ... EOF
吗?另外,你能否让我知道他们对这个 bug 说了什么?或者给我一个相关链接就好了。 - fedorqui<<EOF$varEOF
(在预期位置换行)与引用的 here 字符串相同。漏洞是通过电子邮件报告的,因此没有漏洞跟踪器链接(但)。 - chepner供未来读者参考:
经过与开发人员讨论后,这似乎是 bash
4.2 中的一个 bug,并已在即将发布的 4.3 版本中修复。从devel 分支的更改日志中可以看到:
rrrr. 当 IFS 出现在临时环境中并用于重定向时,修复了多个问题。
虽然始终建议使用引号扩起参数扩展,但 OP 的代码应该无需引号就能按预期工作。
以下是该 bug 的解释。
var="hello:world"
IFS=':' read var1 var2 <<< $var
$var
应该不带引号且只包含单个单词,因为它不包含全局变量IFS
中的任何字符(也就是说,没有空格)。然后read
将看到字符串hello:world
。由于它接收了两个参数,所以它会使用本地IFS
的值进行词分割,生成hello
和world
,并将它们分别赋给var1
和var2
。
bug在于这里的字符串似乎使用传递给read
的“泄漏”IFS
值部分分割。结果,字符串变成了hello world
,但仍然被read
视为单个单词。由于该单词不包含:
,因此read
不会将其拆分成两个单词,并将整个字符串赋给var1
。
在bash
4.3中,如文档所述,$var
的扩展不会经过词分割,作为<<<
运算符的参数;代码:
var="hello:1:2 world"
IFS=: read var1 var2 <<< $var
将var1
设置为hello
,将var2
设置为1:2 world
。