Linux 如果 Ctrl+C 从二进制文件启动的 shell 脚本输入,编译的二进制文件会得到错误的退出代码

Linux compiled binary getting wrong exit code if Ctrl+C entered from a shell script launched by the binary

我这里有一个我认为很奇怪的东西。我有以下环境。

二进制和 ash 脚本分别阻止用户退出。

但是,请注意下面发生的情况:

  1. 允许通过交互式 shell 脚本的正常完成将控制返回给二进制文件。一旦控制 returns 到二进制文件,输入 Ctrl+C 就可以工作并且不允许用户中断程序。 这是正确的行为

错误的地方是:

  1. 在交互式 shell 脚本 运行ning 期间键入几个 Ctrl+C,一旦控制 returns 到二进制文件,退出代码将更改为以下内容shell 脚本在做什么。

这是一个例子:

在 C 代码中,假设我有:

void sigintHandler(int sig_num)
{
    fprintf(stderr, "You are not allowed to exit this program.\n");
    return;
}
void main(void)
{
    signal(SIGINT, sigintHandler);
    int ret = system("/etc/scripts/test.sh");
    printf("test.sh returned: %d exit status.\n", ret);
}

在 test.sh 我有:

#!/bin/ash
# Disable interrupts so that one cannot exit shell script.
trap '' INT TSTP
echo -n "Do you want to create abc file? (y/n): "
read answer
if [ $answer == "y" ];then
    touch /tmp/abc
fi
if [ -f /tmp/abc ]; then
    echo "Returning 1"
    exit 1
else
    echo "Returning 2"
    exit 2
fi

如果我 运行 C 二进制文件通常我会得到正确的退出状态(1 或 2),这取决于文件是否存在。实际上我得到 256 或 512,这表明它将退出代码存储在第二个字节中。重点是每次都能始终如一地工作。

但是现在,如果我在 shell 脚本处于 运行ning 时按下 Ctrl+C(在回答所提出的问题之前)并说我回答 "n",即退出代码 2 . 在 C 二进制文件中,我得到的代码有时是 2(不是 512,表示退出代码现在在低位字节中)但更多时候我得到的代码是 0!即使我看到 shell 脚本回显的消息 "Returning 2",也会发生这种情况。

这让我疯狂地试图弄清楚为什么一个简单的退出代码被搞砸了。

谁能提供一些建议?

非常感谢 艾伦

我发现了问题。

之前我在 shell 脚本中使用 trap '' INT TSTP 来禁用中断。虽然这可以防止 shell 脚本被中止,但它导致了这个 post 中的问题。我怀疑在禁用以这种方式中止 shell 脚本的能力时,上层 shell 框架并没有意识到这一点,它所知道的只是按下 Ctrl+C 或其他任何东西并返回 SIGINT作为退出代码,尽管 shell 脚本本身正在退出。

解决方案是使用:

stty-isig

在 shell 脚本的开头。

这不仅会禁用中断,还会让上层框架知道这是您所做的,因此它会忽略按下 Ctrl+C 的事实。

我在以下页面上找到了此信息:

https://unix.stackexchange.com/questions/80975/preventing-propagation-of-sigint-to-parent-process

谢谢大家, 艾伦