Bash似乎没有将“exit on error”环境标志传递给命令替换shell。
我正在使用大量的命令替换(以避免bash缺少返回值),但是如果子shell中的某些内容失败,我仍然希望整个脚本都会失效。
所以,例如:
set -e
function do_internet {
curl not.valid.address
}
answer=$(do_internet)
我希望脚本停在那里然后,而不是继续。 (我希望设置-e不会因为必须把'|| die'放在所有东西上。
我做错了什么;和/或有什么方法可以解决这个问题吗?
这是一个小例子:
#!/bin/bash
set -e
echo "You should only see this line, and not any other line."
function foo {
false
echo "The above line is false. Figure that one out, Plato."
}
bar=$(foo)
echo $bar
它打印两条线。
(使用GNU bash, version 4.2.25(1)-release (x86_64-pc-linux-gnu)
)
答案 0 :(得分:5)
在使用-e
创建的子广告单元(如Why doesn't bash flag -e exit when a subshell fails?)和使用命令替换(...)
创建的子广告单元之间处理$(...)
之间存在差异,如OP中所示。
根据bash手册中的COMMAND EXECUTION ENVIRONMENT
部分(稍有混淆):
生成的用于执行命令替换的子shell继承父shell的-e选项的值。当不处于posix模式时,bash会清除这些子shell中的-e选项。
无论posix设置如何,-e
仅适用于为命令替换而创建的子shell。所以:
$ set -e
# The subshell has -e cleared
$ echo $(false; echo foo)
foo
$ set -o posix
# Now the subshell has -e, so it terminates at `false`
$ echo $(false; echo foo)
$
尽管如此,-e
确实适用于执行仅设置变量的命令。所以
set -e
a=$(false)
将终止shell。
但是,-e
不适用于函数中的各个命令。在
fail() {
false
echo "failed"
}
fail
的返回值为0(即成功),因为echo
(执行的最后一个命令)成功。因此
a=$(fail) && echo ok
会将a
设置为failed
,然后打印ok