【问题标题】:trap exec return code in shell script在 shell 脚本中捕获 exec 返回代码
【发布时间】:2018-05-13 10:04:13
【问题描述】:

我必须在 shell 脚本中使用 exec 运行命令,并且我需要捕获退出代码以防出错并运行另一个命令,例如

#!/bin/sh
set +e
exec command_that_will_fail
if [ $? -eq 1 ]; then
    echo "command failed, running another command"
fi

我知道 exec 替换了当前的 shell 并继续,我的问题是如果 exec 不成功,我需要运行另一个命令。

【问题讨论】:

    标签: shell error-handling exec


    【解决方案1】:

    如果在尝试运行进程时出现一些即时错误,您的代码可以工作:

    $ echo 1
    1
    $ echo $?
    0
    $ exec asd123
    -bash: exec: asd123: not found
    $ echo $?
    127
    

    如果找到可执行文件并启动,那么它不会返回,因为它将超过整个脚本并且永远不会再次返回到 bash。

    例如,这永远不会返回:

    $ exec grep asd /dev/null
    

    (grep的退出码是1,但是父shell被超越了,所以没人查)

    如果您想在这种情况下从进程中获取退出代码,则必须将其作为子进程启动,即不使用 exec(仅command_that_will_fail)。在这种情况下,bash 进程将充当主管,等待子进程完成并检查退出代码。

    【讨论】:

    • 该命令必须使用 exec,因为它在一个 docker-entrypoint 脚本中(我相信使用了 exec,所以它继续作为 PID=1 )
    • 那更糟。通常 PID=1 是 init(根进程)。如果它死了,系统就死了,没有退出代码。
    • 为什么你的进程需要PID=1?过程是什么?为什么需要退出代码,你打算用它做什么?
    • 此脚本作为 docker 容器的入口点运行,其想法是在出现问题时尝试替代方案,但仍运行容器
    • 我还是不明白。为什么 bash 脚本不能成为 PID=1 的入口点,你的真实进程是一个 PID=222 的子进程,如果它因错误而死,你会产生一个 PID=333 的替代方案?
    猜你喜欢
    • 1970-01-01
    • 2014-10-21
    • 2014-03-17
    • 1970-01-01
    • 2013-08-28
    • 2010-11-27
    • 1970-01-01
    • 1970-01-01
    • 2023-03-30
    相关资源
    最近更新 更多