为什么bash4以不同的方式扩展大括号?

问题描述:

遗留系统之一升级到bash4,其大部分脚本停止工作。我已经缩小到如何在<(cmdA ...|cmdB ... file{1,2}|cmdZ ...)内展开大括号。为什么bash4以不同的方式扩展大括号?

为了说明差异更好:

BEFORE(3.2.25庆典):

[[email protected]:~]$ bash -version|head -1 
GNU bash, version 3.2.25(1)-release (x86_64-redhat-linux-gnu) 
[[email protected]:~]$ cat <(echo sort file{1,2}) 
sort file1 
sort file2 
[[email protected]:~]$ join <(sed 's/\r//g;s/^[^:]*://' file{1,2}|LANG=C sort) 
[[email protected]:~]$ 

AFTER(bash的4.1.2):

[[email protected]:~]$ bash --version|head -1 
GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu) 
[[email protected]:~]$ cat <(echo sort file{1,2}) 
sort file1 file2 
[[email protected]:~]$ join <(sed 's/\r//g;s/^[^:]*://' file{1,2}|LANG=C sort) 
join: missing operand after `/dev/fd/63' 
Try `join --help' for more information. 
[[email protected]:~]$ 

它是一个“硬编码“(和预期?)更改为bash4?或者是这种扩展的行为受某些bash级设置(如set -B/set +B)控制,并且可以切换回旧/ legacy/bash3模式?我宁愿改变一些shell的开关(而不是重写一堆脚本)。

如果这(bash3)“功能”是一个bug修正或改进过程中切断 - 我很惊讶,因为旧的(bash3)语法允许以节省打字一吨......

+3

哦,等一下。你期望生成两个不同的*进程替换*,而不是'sed'的两个参数?我不知道那是**有史以来**符合正确的,记录在案的行为......也就是说,AFAIK,你的代码取决于一个错误。 –

+0

@CharlesDuffy - 这就是它一直工作的原因(对于我和脚本),直到bash4升级 - Vlad

+3

@Vlad这看起来像一个bug,他们在Bash 4中修复了这个bug。你应该期望' Barmar

原来的行为是没有记录(并且违背一般规则,即代码包含在流程替换中,例如子外壳或类似的上下文,它们将以与它相同的方式进行解析)。

因此,这是一个错误,而不是一个功能。这个bug在bash-4.0-alpha中修复。引用CHANGES条目:

rr。 Brace扩展现在允许进程替换通过不变。

没有用于恢复此更改的运行时标志可用。

+1

我在同一时间挖掘,发现另一个受影响的用户(http://wiki.bash-hackers.org/syntax/expansion/brace),然后在CHANGES中找到相同的条目,并找到了导致“提交bash-20080724快照”。为了简化我的目标 - 我将重新编译自定义bash4作为我的包装盒,同时只恢复优先级更改,然后重新检查脚本。悲伤的是它没有暴露在运行时标志来简化我的目标。让我赞成所有的答案,谢谢你! – Vlad