如何让一个bash子shell退出主调用shell脚本?

时间:2018-05-28 13:16:32

标签: bash exit exit-code subshell

拥有以下bash脚本:

#!/bin/bash

set -e

function foo() {
  # commands that might fails and I want to exit my script
  ...
  echo "result I need as output"
}

my_var=$(foo)

echo "I don't want this if there is an error inside foo"

使用set -e(在bash 4.4.19中)似乎不适用于子shell,即最后echo命令仍在执行中)。如果foo中的任何命令以非零退出代码终止,如何编写代码以使脚本退出。

我正在使用bash GNU bash, version 4.4.19(1)-release (x86_64-apple-darwin16.7.0),调用我的脚本的结果是(用无效的命令head -this替换点:

$ ./my_script
head: illegal option -- t
usage: head [-n lines | -c bytes] [file ...]
I don't want this if there is an error inside foo

1 个答案:

答案 0 :(得分:2)

已从评论

更改

管道命令的退出状态是最后一个命令的退出状态,这可以使用set -o pipefail进行更改,以便管道退出状态为<>0,任何命令退出状态为{{ 1}}。

第一个答案

当您使用<>0选项时,该函数返回非-e退出代码就足够了,例如0

在更一般的情况下(没有return 1),使用显式退出可能更好

set -e

就足够了,因为错误可以通过子shell写入标准错误(继承)。

否则仔细阅读手册可以解释为什么它不能按预期工作

  

组   -e

     

如果[...]返回非零状态,则立即退出。如果失败的命令是紧跟在while或until关键字之后的命令列表的一部分,if语句中的测试的一部分,在&amp;&amp ;;中执行的任何命令的一部分,则shell不会退出。或||列表除了最后一个&amp;&amp;之后的命令或||,[...]。

     

此选项分别适用于shell环境和每个子shell环境(请参阅命令执行环境),并且可能会导致子shell在执行子shell中的所有命令之前退出。

     

[...]

从命令执行环境

  

生成的用于执行命令替换的子shell继承父shell的-e选项的值。当不在POSIX模式时,Bash清除这些子shell中的-e选项。