如何清除父进程设置的子进程中的陷阱?

时间:2016-10-06 23:12:21

标签: linux unix process sigkill sigterm

进程A设置陷阱。然后它创建一个子进程B.如何清除进程A设置的陷阱?

processA

#! /bin/bash
# processA.sh
trap '' 15
sh processB.sh

进程B

#! /bin/bash
# processB.sh    
echo "Current trap"
trap -p    
echo "Clearing trap 15"
trap - 15    
echo "New trap"
trap -p

输出

Current trap
trap -- '' TERM
Clearing trap 15
New trap
trap -- '' TERM

在上面的示例中,我正在清除子进程B中的陷阱,但它没有被清除。操作系统是Linux。

1 个答案:

答案 0 :(得分:0)

通常,您使用trap 15取消信号15的陷阱。这将包括当当前shell开始忽略它时将忽略的信号重置为默认值。

然而,一些实验(在macOS Sierra 10.12上使用Bash 3.2.57)显示,如果在进程启动时忽略了信号(从父进程继承),那么您无法重置为默认处理 - 它继续被忽略了。此外,trap ': do nothing' 15后跟trap 15的尝试无法完成此任务。

我编写了一个名为iqon的C程序(中断,退出 - 1989年的第一个版本),以确保信号被执行后的命令捕获(或忽略)。

iqon -s 15 -- bash processB.sh

此主题作品的变化。

请注意,iqon的简单版本仅将信号SIGTERM设置为默认状态(无参数处理),可以简单如下:

#include <signal.h>
#include <stdio.h>
#include <unistd.h>

int main(int argc, char **argv)
{
    if (argc <= 1)
    {
        fprintf(stderr, "Usage: %s cmd [arg ...]", argv[0]);
        return 1;
    }
    signal(SIGTERM, SIG_DFL);
    execvp(argv[1], &argv[1]);
    perror(argv[1]);
    return 1;
}
显然,你可以毫不费力地使它变得更加复杂。我的版本支持这样的帮助信息:

Usage: iqon [-dhV] [-s signal] [-i signal] cmd [args ...]
  -d         Set interrupt and quit to default
  -h         Print this help and exit
  -i signal  Ignore signal (number)
  -s signal  Set default for signal (number)
  -V         Print version information and exit

默认设置(设置中断并退出默认行为)是其最初目的的遗留物 - 用于从4GL创建的程序中运行程序,其中中断和退出信号被忽略。这也是名称的来源:i nterrupt和q uit on