2015-10-06 79 views
2

我下的印象是exit将终止当前的bash脚本不管是什么,并且有以下错误处理程序在我的脚本的顶部:

function err { 
    printf "\e[31m$1\e[0m\n" 1>&2 
    exit 1 
} 

它的工作像大多数情况下,魅力直到这条线:

item=$(myfunc $1) 

通常情况下,该行正常工作,与MYFUNC的STDOUT倒入$item,如预期。当myfunc通过上面看到的err函数引发错误时,会出现此问题。 $()最终吞噬非零回报,并防止退出退出脚本本身。如果我理解正确,问题是$()实际上产生了一个新的子shell(就像弃用的反引号一样),但是我知道没有其他方法将函数的输出捕获到bash中允许exit工作的变量中。

我也尝试过使用set -e,并且没有任何运气。有人可以建议如何构建我的错误处理程序,以便在这些情况下退出脚本吗?

+1

'$()'最终吞噬了一切,因为*命令替换*在* subshel​​l *中占有一席之地。什么是关于subshel​​l的bash规则? *子外壳中没有任何操作可以影响父进程... *是的,您可以返回退出状态('$?'),但您无法执行其他任何操作。 –

回答

5

可以测试分配的结果:

if item=$(myfunc "$1") 
then : Function worked 
else : Function failed 
fi 

这个测试运行的命令在子shell的$(…)用途退出状态。


实际上并没有使用功能,您可以体验:

$ if item=$(echo Hi; exit 1); then echo "$item - OK"; else echo "$item - OH"; fi 
Hi - OH 
$ if item=$(echo Hi; exit 0); then echo "$item - OK"; else echo "$item - OH"; fi 
Hi - OK 
$ 

或者,如果功能被认为是至关重要的,那么:

$ err() { exit $1; } 
$ myfunc() { echo Mine; err $1; } 
$ if item=$(myfunc 1); then echo "$item - OK"; else echo "$item - OH"; fi 
Mine - OH 
$ if item=$(myfunc 0); then echo "$item - OK"; else echo "$item - OH"; fi 
Mine - OK 
$ 

使用bash 3.2.57在Mac OS测试X 10.11埃尔卡皮坦。

+0

嗯,不管怎样,它似乎总是会为我工作的情况。也许出于同样的原因,大卫建议的'$?'也总是保持为0.看起来这是吃掉退出标志的任务。 –

+0

这适用于我。 +1。我用'a = $(false)测试了它; echo code = $?'和'a = $(true);回声代码= $?'。 @Alexander,如果它不适合你,请确保'myfunc'(你没有告诉我们)正确设置退出代码。 – John1024

+0

只是不要在命令提示符下调用'err' ... –

0

为了什么值得你也不能使用bash短路评估来测试函数的退出状态。它将测试赋值给变量。

例如。 而

[[ $(myfunc "$1") ]] && echo success || echo failure 

[[ myfunc "$1" ]] && echo success || echo failure 

是相当普遍的,可能做什么的预期,

[[ item=$(myfunc "$1") ]] && echo success || echo failure 

始终返回即使MYFUNC返回非零成功。您必须使用if和else来测试退出状态。