Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux编译的二进制文件在Ctrl+;C从一个由二进制文件启动的shell脚本中输入_C_Linux_Shell_Ash - Fatal编程技术网

Linux编译的二进制文件在Ctrl+;C从一个由二进制文件启动的shell脚本中输入

Linux编译的二进制文件在Ctrl+;C从一个由二进制文件启动的shell脚本中输入,c,linux,shell,ash,C,Linux,Shell,Ash,我这里有一个我认为很奇怪的东西。我有以下环境 一个Linux编译的二进制文件,它设置一个信号处理程序来禁用Ctrl+C、Ctrl+z等。这是通过调用signal on:SIGINT、SITTSTP和SIGQUIT来完成的。信号处理程序只打印一条错误消息,说明不允许用户中止程序 设置信号处理程序后,二进制文件调用一个交互式ash脚本 此交互式ash脚本还禁用所有中断脚本的方法。它在一开始就用“trap”“INT-TSTP”实现了这一点。这是可行的,如果输入Ctrl+C等,它只会将控制字符回显到终

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

  • 一个Linux编译的二进制文件,它设置一个信号处理程序来禁用Ctrl+C、Ctrl+z等。这是通过调用signal on:SIGINT、SITTSTP和SIGQUIT来完成的。信号处理程序只打印一条错误消息,说明不允许用户中止程序
  • 设置信号处理程序后,二进制文件调用一个交互式ash脚本
  • 此交互式ash脚本还禁用所有中断脚本的方法。它在一开始就用“trap”“INT-TSTP”实现了这一点。这是可行的,如果输入Ctrl+C等,它只会将控制字符回显到终端,但不会退出
二进制和ash脚本分别阻止用户退出

但是,请注意以下情况:

  • 允许通过正常完成交互式shell脚本将控件返回到二进制文件。一旦控件返回到二进制,输入Ctrl+C将起作用,并且不允许用户跳出程序这是正确的行为
  • 错误之处在于:

  • 在交互式shell脚本运行期间键入几个Ctrl+C,一旦控件返回到二进制,退出代码将更改为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脚本运行时(在回答前面的问题之前)按Ctrl+C并说我回答“n”,这是退出代码2。在C二进制代码中,我返回的代码有时是2(不是512,表示退出代码现在在较低的字节中),但更多时候我返回的代码是0!即使我看到shell脚本响应的消息“returning2”,这种情况也会发生

    试图弄明白为什么一个简单的退出代码会被弄乱,这让我抓狂

    有人能提供一些建议吗

    多谢 艾伦

    我发现了这个问题

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

    解决方案是使用:

    stty-isig

    在shell脚本的开头

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

    我在下一页找到了这些信息:

    谢谢大家,,
    Allen

    :“返回值是一个“等待状态”,可以使用waitpid(2)中描述的宏进行检查。(即WIFEXITED()、WEXITSTATUS()等)。”不同的shell是否会出现相同的症状?(例如,使用#!/bin/bash、#!/bin/sh、#!/bin/dash、#!/bin/ksh等)@kaylum WIFSIGNALED返回true,WTERMSIG返回2,即SIGINT。但是问题是这个中断被禁用了,所以shell脚本根本没有终止。这种情况会发生,会让你大吃一惊。我没有安装其他的。谢谢艾伦