IFS随Bash 4.2而变化

时间:2014-07-24 09:21:41

标签: bash ifs

运行这些命令可以得到预期的结果

$ bash --version
GNU bash, version 4.1.11(2)-release

$ foo=(111 222 333)

$ IFS=, cat <<< "${foo[*]}"
111,222,333

然而,它出现在Bash 4.2中,IFS值被忽略

$ bash --version
GNU bash, version 4.2.0(1)-release

$ foo=(111 222 333)

$ IFS=, cat <<< "${foo[*]}"
111 222 333

造成这种差异的原因是什么?

我在这里找到了答案

http://lists.gnu.org/archive/html/bug-bash/2014-03/msg00065.html

看起来这一直是一个错误。据切特说, 重定向永远不应该有权访问临时环境 (在这种情况下为IFS

1 个答案:

答案 0 :(得分:7)

我发现4.2的行为正确,因为在分配评估之前,应首先进行分词:

IFS=, cat <<< "${foo[*]}"

我认为IFS的新价值应仅影响cat,而不影响<<< "${foo[*]}"

正确的方法是

IFS=, eval 'cat <<< "${foo[*]}"'

对于保守的方法,我们可以使用函数:

function t { cat <<< "${foo[*]}"; }
IFS=, t

我也猜测它与此有关:

m.  Fixed a bug that caused here documents to not be displayed correctly
    when attached to commands inside compound commands.

更新

另一个令人困惑的行为可以在4.2中找到,已经在4.3中修复。通过执行IFS=, cat <<< "${foo[*]}""${foo[*]}"扩展为"111 222 333"(不受IFS影响),如cat 111 222 333所示。但是,当我们执行IFS=, read bar <<< "${foo[*]}"; echo "$bar"时,输出将为111,222,333,并且看起来好像"${foo[*]}"扩展为"111,222,333"。这种不一致的行为不再发生在Bash 4.3中,而Bash 4.3的行为可能是一种修复。