捕获退出命令的退出代码


10

我在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

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

我当时在猜测:

exec exit 3

但它会显示错误消息:exec: exit: not found。我能做什么?:)


1
是的exec exit 3,不是"exec: exit: not found"

7
我不明白这个问题。为什么不设置exit_code=3exit 3完全消除界限呢?
wjandrea

@wjandrea不仅仅是实际的概念问题

2
对我来说仍然没有意义。如果您实际上没有退出,为什么会有退出代码?
Barmar

1
@Barmar每个进程都有一个退出代码。大多数试图回答问题的人都将问题解释为“我可以用脚本中的'exit 3'替换什么,以便它设置$?变量但不退出脚本”?
icarus

Answers:


32

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

(exit 3)

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


同样,出于调试目的,设置exit_code="3"测试也将变得非常简单
Centimane


12

exit是内置的bash,所以您不能这样exec做。根据bash的手册

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

综上所述,我想说的唯一选择是将所需的退出状态存储在变量中,然后exit $MY_EXIT_STATUS在适当时存储。


嗯,您如何看待@ G-man的想法?

2
也许我误解了您要完成的工作。如果您只是想进行设置$?(尽管我不确定您为什么这么做),那似乎是一个可靠的答案。如果只想将其设置为某个不成功的值,false则是另一种选择。
solarshado

10

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

ret() { return "${1:-255}"; }

并用来ret代替您的呼叫exit。这样可以避免在当前接受的答案中创建子外壳的效率低下。

一些测量。

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

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

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

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

显然,这是一种综合测量,但总的来说。如果使一切比它们所需的速度慢100倍,那么您最终将获得缓慢的系统。0.0


2
@iBug不需要多余的空间。
icarus

关于创建子外壳的效率低下的好处。我读过一些shell可能足够聪明,可以在这种情况下优化派生,但是bash并不是其中之一。
G-Man说'Resstate Monica''De​​c

3

关于exec exit 3...它会尝试运行一个名为的外部命令exit,但是没有一个外部命令,因此会出现错误。因为必须完全exec 替换外壳,所以它必须是外部命令,而不是内置在外壳中的命令。这也意味着即使您有一个名为的外部命令exitexec exit 3也不会返回继续执行您的shell脚本,因为该shell将不再存在


1
我猜你可以做到exec bash -c "exit 3",但是目前我想不到这样做的理由,而不是公正exit 3
David Z

1
@DavidZ,无论如何,exec“ ing”或exit“ ing”都会停止脚本,这似乎不是问题所要的。
ilkkachu

3

您可以使用Awk做到这一点:

awk 'BEGIN{exit 9}'

或Sed:

sed Q9 /proc/stat

...或带壳:sh -c 'exit 9'
ilkkachu

1
@ilkkachu如果您愿意这样做,那么您也可以按照(exit 9)公认的答案进行操作
Steven Penny
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.