【发布时间】:2017-08-08 07:44:18
【问题描述】:
其中一个旧系统升级到 bash4 并且其大部分脚本停止工作。我已将其范围缩小到如何在 <(cmdA ...|cmdB ... file{1,2}|cmdZ ...) 中扩展大括号。
为了更好地说明差异:
之前(bash 3.2.25):
[root@host1:~]$ bash -version|head -1
GNU bash, version 3.2.25(1)-release (x86_64-redhat-linux-gnu)
[root@host1:~]$ cat <(echo sort file{1,2})
sort file1
sort file2
[root@host1:~]$ join <(sed 's/\r//g;s/^[^:]*://' file{1,2}|LANG=C sort)
[root@host1:~]$
之后(bash 4.1.2):
[root@host2:~]$ bash --version|head -1
GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu)
[root@host2:~]$ cat <(echo sort file{1,2})
sort file1 file2
[root@host2:~]$ 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.
[root@host2:~]$
这是对 bash4 进行的“硬编码”(并且是预期的?)更改吗?或者这种扩展的行为是否由一些 bash 级别的设置(如set -B/set +B)控制,并且可以切换回旧/旧/bash3 模式?我宁愿更改一些 shell 范围的开关(而不必重写一堆脚本)。
如果这个(bash3)“功能”在错误修复或改进期间被切断 - 我很惊讶,因为旧的(bash3)语法允许在打字时节省大量......
【问题讨论】:
-
哦,等等。您希望生成两个不同的进程替换,而不是
sed的两个参数?我不知道那是曾经符合正确的,记录在案的行为......也就是说,AFAIK,你的代码取决于一个错误。 -
@CharlesDuffy - 在 bash4 升级之前,它一直是这样工作的(对我和脚本来说) -
<(cmd {a,b})确实扩展到两个<(cmd a) <(cmd b)并被传递到 join/etc。那些脚本广泛使用此功能,将其嵌套到多个级别并测试脚本(不想用我的胖手指触摸它并产生新的错误)。 -
@Vlad 这似乎是一个错误,他们在 Bash 4 中修复了。您应该期望
<(...)中的命令与任何其他命令一样被解析,所以<(cmd {a,b})应该等同于<(cmd a b). -
这种误解是我欣赏 Rich Hickey 在 Clojure 中的政策的地方之一,明确而大声地宣称虽然保证了文档功能的向前兼容性,但在任何情况下都不会是可以依赖的无证行为。
标签: bash shell rhel curly-braces expansion