使用命令替换或类似方法,但仍退出脚本(使用set -e)

coi*_*iax 4 bash

Bash似乎没有将“错误退出”环境标志传递到命令替换shell中。

我正在使用大量命令替换(以解决bash缺少返回值的问题),但是我仍然希望整个脚本能够在子shell中失败的情况下崩溃。

因此,例如:

set -e    

function do_internet {
    curl not.valid.address
}

answer=$(do_internet)
Run Code Online (Sandbox Code Playgroud)

我希望脚本先停在那里,然后再不继续。(我希望设置-e不必在所有内容上都加“ ||死”。

难道我做错了什么; 和/或有没有解决的办法?

这是一个小例子:

#!/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
Run Code Online (Sandbox Code Playgroud)

它打印两行。(使用GNU bash, version 4.2.25(1)-release (x86_64-pc-linux-gnu)

ric*_*ici 5

使用-e创建的子外壳之间的处理有所不同(...),如子外壳失败时为什么bash标志-e不退出?,以及使用命令替换创建的子外壳$(...),如在OP中一样。

根据COMMAND EXECUTION ENVIRONMENTbash手册中的部分(有点令人困惑):

为执行命令替换而产生的子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)

$
Run Code Online (Sandbox Code Playgroud)

尽管如此,-e它确实适用于仅设置变量的命令的执行。所以

set -e
a=$(false)
Run Code Online (Sandbox Code Playgroud)

将终止外壳。

但是,-e不适用于功能中的各个命令。如果是

fail() {
  false
  echo "failed"
}
Run Code Online (Sandbox Code Playgroud)

返回值为fail0(即成功),因为echo(最后执行的命令)成功。所以

a=$(fail) && echo ok
Run Code Online (Sandbox Code Playgroud)

将设置afailed,然后打印ok