从捕获输出的函数中退出一个bash脚本

我想完全终止/退出一个错误的bash shell脚本,但使用一个函数error ,让我在终止之前显示一个debugging输出。 现在我遇到这样的问题:如果通过反引号或$()捕获函数的输出,错误函数中的exit 1语句将不会终止shell脚本。

这是我的示例脚本:

  #!/bin/bash function error () { echo "An error has occured: $1" exit 1 } function do_sth () { if [ $1 -eq 0 ]; then error "First param must be greater than 0!" else echo "OK!" fi } RESULT=`do_sth 0` echo "This line should never be printed" 

我怎样才能立即终止在error()函数中的脚本?

命令替换的问题是,一个子shell开始执行do_sthexit 1然后终止这个子shell而不是主bash。

你可以通过追加|| exit $?来解决这个问题 || exit $? ,从命令替换退出代码退出

 RESULT=`do_sth 0` || exit $? 

如果要显示错误消息,请将其重定向到stderr

 echo "An error has occured: $1" >&2 
 RESULT=`do_sth 0` || exit $? 

然后回显“发生错误:$ 1”>&2

没有办法避免这样一个事实,即subshel​​l不能直接使父对象终止:父对象必须计算从subshel​​l返回的值。 一个常见的技术是陷阱出口,并在陷阱函数中输出错误信息。 由于您在子外壳中生成错误消息,因此您不能简单地将消息分配给变量,否则可能会这样做,但可以使用文件系统。 请注意,这个想法是非常愚蠢的,只是把错误信息写到stderr就简单多了。 这就是它的原因,这就是为什么它是由儿童继承。 就像是:

 #!/bin/sh trap final 0 2 15 # Create a temporary file to store error messages. This is a terrible # idea: it would be much better to simply write error messages to stderr, # but this code is attempting to demonstrate the technique of having the # parent print the message. Perhaps it would do better to serve as an example # of why reporting your children's mistakes is a bad idea. The children # should be responsible for reporting their own errors. Doing so is easy, # since they inherit file descriptor 2 from their parent. errmsg=$( mktemp xxxxx ) final() { test "$?" = 0 || cat $errmsg rm -f $errmsg } >&2 # Must emphasize one more time that this is a silly idea. The error # function ought to be writing to stderr: eg echo "error: $*" >&2 error() { echo "error: $*" > $errmsg; exit 1; } do_sth() { if test "$1" -eq 0; then error "First param must be greater than 0!" else echo "OK!" fi } result=$( do_sth 0 ) || exit 1 echo not printed 

看起来(聪明的)答案是由@FatalError在另一个问题的答案, 在这里

这应该工作…

 #!/bin/bash trap "exit 1" 50 #exit process after receiving signal 50. function myerror () { echo "An error has occured: $1" >&2 } function do_sth () { if [ $1 -eq 0 ]; then myerror "First param must be greater than 0!" kill -50 $(ps --pid $$ -opid=) #uncommon signal 50 is used. else echo "OK!" fi } RESULT=`do_sth 1` echo $RESULT RESULT=`do_sth 0` echo $RESULT echo "This line should never be printed"