为什么在bash 3.2中,使用进程替换时source命令不起作用?

15

我有以下的 shell 脚本:

cat <(echo foo)
source <(echo bar=bar)
echo $bar

然而在 GNU bash 3.2 和 4.3 中,它的工作方式有所不同,如下所示:

$ /bin/bash foo.sh 
foo

3.2.53(1)-release

$ /usr/local/bin/bash foo.sh 
foo
bar
4.3.33(1)-release

为什么这只适用于一个版本?这是一个错误还是新增的功能?

进程替代似乎运行良好,但在对文件进行源操作时出现问题。

如果这是预期的行为,那么我应该使用哪种语法来从标准输入中“source”某些内容,以便在不同的bash版本之间兼容?


重复的问题:https://dev59.com/_GPVa4cB1Zd3GeqP7qVb#10527064? - Charles Duffy
1个回答

19
这是bash 3.2中已知的限制。为了解决此问题:
source /dev/stdin <<<"$(echo bar=bar)"

...或者,同样地:

source /dev/stdin <<<"$(cat <(...))"

1
eval 的行为并不完全相同;例如,查看顶层的 return 语义或用于堆栈跟踪报告的各种数组。 - Charles Duffy
太棒了!这也适用于 curlsource /dev/stdin <<<"$( curl $url )" - wisbucky
这个限制在GNU bash 4.4.19(1)中仍然存在。 - Chad Skeeters
@ChadSkeeters,我不相信那是真的。你确定你没有在像msys2 Windows builds这样的平台上使用破损的进程替换吗?请看https://ideone.com/amkRVh中bash 5的正常运行;如果我能够链接到一个在线的4.x沙盒,我也会这样做,但我知道的那个只有IRC而不是基于Web的。 - Charles Duffy
1
@ChadSkeeters,我怀疑即使你在Homebrew中安装了bash 4.4,你的交互式shell仍然是苹果的3.2.57(1)。确保你运行echo "$BASH_VERSION"来检查你正在使用的版本,而不是bash --version - Charles Duffy
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接