【问题标题】:exit from bash script that uses $()退出使用 $() 的 bash 脚本
【发布时间】:2016-02-26 00:58:43
【问题描述】:

我的印象是exit 无论如何都会终止当前的 bash 脚本,并且在我的脚本顶部有以下错误处理程序:

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

在这行之前,它在大多数情况下都很有效:

item=$(myfunc $1)

通常,该行工作正常,myfunc 的 STDOUT 按预期转储到$item。当myfunc 通过上面看到的err 函数引发错误时,就会出现问题。 $() 最终吞下了非零返回并保护退出脚本本身退出。如果我理解正确,问题是$() 实际上产生了一个新的子shell(就像不推荐使用的反引号一样),但我知道没有其他方法可以将函数的输出捕获到允许exit 的 bash 中的变量中上班。

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

【问题讨论】:

  • $() 最终吞噬了一切,因为 command-substitution 在 subshel​​l 中进行。关于 subshel​​l 的 bash 规则是什么? 在子 shell 中所做的任何事情都不会影响父进程... 是的,您可以返回退出状态 ($?),但您不能做任何其他事情。

标签: bash


【解决方案1】:

你可以测试一下作业的结果:

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
$

在 Mac OS X 10.11 El Capitan 上使用 Bash 3.2.57 进行测试。

【讨论】:

  • 嗯,无论如何,它似乎总是对我来说总是进入worked 案子。并且可能出于同样的原因 $? David 建议也始终保持 0。看起来这是在吃退出标志的任务。
  • 这对我有用。 +1。我用a=$(false); echo code=$? 和a=$(true); echo code=$? 对其进行了测试。 @Alexander,如果它不适合您,请确保 myfunc(您尚未向我们展示)正确设置退出代码。
  • @DavidC.Rankin:当您不想再使用它们时,这是使函数未定义的一种方法。 :) (另一种或至少另一种取消定义它们的方法是将unset -f err myfunc 作为命令。)
  • 我没有展示 myfunc 的原因是它相当而且似乎并不相关。经过更多的播放和减少,$? 似乎由于local 声明和同一行的赋值而被重置。
【解决方案2】:

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

例如。 而

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

或

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

相当普遍,可能会达到预期,

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

即使 myfunc 返回非零,也总是返回成功。您必须使用 if then else 来测试退出状态。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-29
    • 2017-12-03
    • 1970-01-01
    • 2023-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多