捕获退出命令的退出码

10 bash shell-script exit exec exit-status

我在 bash 脚本中有这个:

exit 3;

exit_code="$?"

if [[ "$exit_code" != "0" ]]; then
    echo -e "${r2g_magenta}Your r2g process is exiting with code $exit_code.${r2g_no_color}";
    exit "$exit_code";
fi
Run Code Online (Sandbox Code Playgroud)

看起来它会在退出命令后立即退出,这是有道理的。我想知道是否有一些简单的命令可以提供退出代码而无需立即退出?

我猜:

exec exit 3
Run Code Online (Sandbox Code Playgroud)

但它给出了一条错误消息:exec: exit: not found。我能做什么?:)

G-M*_*ca' 32

如果您有一个脚本运行某个程序并查看程序的退出状态(使用 $?),并且您想通过执行一些 导致$?设置为某个已知值(例如,  3)的操作来测试该脚本,只需

(exit 3)
Run Code Online (Sandbox Code Playgroud)

括号创建一个子壳。然后该exit命令使该子 shell 以指定的退出状态退出。


sol*_*ado 12

exit是内置的 bash,所以你不能exec。根据bash 的手册

Bash 的退出状态是脚本中执行的最后一个命令的退出状态。如果没有执行任何命令,则退出状态为 0。

将所有这些放在一起,我想说您唯一的选择是将所需的退出状态存储在变量中,然后exit $MY_EXIT_STATUS在适当的时候存储。

  • 也许我误解了你想要完成的事情。如果你只是想设置 `$?`(虽然我不确定你为什么会这样做),这似乎是一个可靠的答案。如果您只想将其设置为某个不成功的值,`false` 是另一种选择。 (2认同)

ica*_*rus 10

您可以编写一个函数,返回作为参数给出的状态,或者255如果没有给出。(我称它为ret“返回”其值。)

ret() { return "${1:-255}"; }
Run Code Online (Sandbox Code Playgroud)

并使用ret来代替您对 的调用exit。这避免了在当前接受的答案中创建子外壳的低效率。

一些测量。

time bash -c 'for i in {1..10000} ; do (exit 3) ; done ; echo $?'
Run Code Online (Sandbox Code Playgroud)

在我的机器上大约需要 3.5 秒。

 time bash -c 'ret(){ return $1 ; } ; for i in {1..10000} ; do ret 3 ; done ; echo $?'
Run Code Online (Sandbox Code Playgroud)

在我的机器上大约需要 0.051 秒,快 70 倍。放入默认处理仍然让它快 60 倍。显然,循环有一些开销。如果我将循环体更改为只是:true然后将时间减半为 0.025,则完全空的循环是无效的语法。添加;:到循环中显示此最小命令需要 0.007 秒,因此循环开销约为 0.018。从这两个测试中减去这个开销表明该ret解决方案快了 100 倍以上。

显然这是一个综合测量,但事情加起来。如果你让一切都比他们需要的慢 100 倍,那么你最终会得到缓慢的系统。0.0

  • @iBug 不需要额外的空间。 (2认同)