出错时退出子shell

时间:2015-04-28 17:24:59

标签: bash

我目前正在使用这样的东西:

(
false
true 
) && echo "OK" || echo "FAILED";

它不起作用。如果某些内容失败,我希望子shell退出并返回错误(在这种情况下为false)。目前,只有在最后一个命令失败时才会失败。

它应该只退出当前的子shell而不是整个脚本。

我将这个脚本提供给人们,我不希望他们看到所有的输出,但如果脚本成功与否,他们仍然会给他们某种响应。

编辑:上面子shell中的命令只是一个例子。我想在子shell 中运行多个命令,而不检查每个命令后的返回值。类似set -e for subshel​​ls。

Edit2:我尝试在子shell中添加set -e。也许我做错了但它并没有改变我的脚本的行为。它没有使用非0代码停止执行或退出子shell。

(
set -e
false
echo "test"
) && echo "OK" || echo "FAILED"; 

首先打印测试,然后确定。它应该因为错误而打印FAILED。

3 个答案:

答案 0 :(得分:4)

编辑问题:

  

类似set -e for subshel​​ls。

好吧,你可以为子shell做set -e

( set -e
my
commands
)

您无法隐式地使只是您的子shell具有errexit选项。您可以使用eval做一些技巧,或者使用子进程作为shell(即使子进程与子shell不同),例如

errexit_shell() {
    bash -e
}

但由于各种原因,这些选项都是不可取的,其中最重要的是可读性。在这种情况下,你最好的选择就是调整你的整个脚本以使用set -e,并且你的子壳将会出现。

原来的问题:

只需捕获指示成功或失败的部件的状态:

(
    cat teisatrt
    status=$?
    echo "true"
    exit "$status"
) && echo passed || echo failed

(当然,如果您只想知道该文件是否可读,请不要使用它,只需使用test -r。)

答案 1 :(得分:2)

bash set -e 在条件表达式(如 foo || true)中的这种效果是已知的并且被认为是一个问题。我认为一般都讨厌set -e和shell脚本。

第一个链接提出以下建议。它在小例子中看起来不错,但在现实世界中可能不太清楚。

  

通过将一系列命令串联起来进行自己的错误检查   与“&&”这样:

mkdir abc &&
cd abc &&
do_something_else &&
last_thing ||
{ echo error >&2; exit 1; }
     

一些重要说明:您不需要尾随反斜杠。你没有   缩进以下行。你必须坚持每行80个字符   每个人都可以在最后看到“&&”或“||”。如果你需要混合AND   和OR,与{this braces}组合,不产生子shell。

答案 2 :(得分:0)

如你所知,你将整个子shell的输出重定向到/ dev / null,所以你永远不会看到你的" true"回声。您应该将子shell中的重定向移动到您真正想要的命令。为了在cat失败时退出子shell,您需要在cat运行后检查失败。如果您没有,那么正如您所指出的那样,其返回代码将被以下语句删除。所以像这样:

echo "Installing App"
(
cat teisatrt &> /dev/null || exit 1
echo "true"
) && echo "OK" || echo "FAILED";