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

标签 linux unix process sigkill sigterm

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

进程A

#! /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。

最佳答案

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

但是,一些实验(在 macOS Sierra 10.12 上使用 Bash 3.2.57)表明,如果在进程启动时信号被忽略(从父级继承),那么您无法重置为默认处理 - 它继续被忽略。此外,像 trap ': do nothing' 15trap 15 这样的尝试不会完成这项工作。

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

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 创建的程序中运行程序,其中中断和退出信号被忽略。这也是名称的来源:interrupt and quit on

关于linux - 如何清除父进程设置的子进程中的陷阱?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39907012/

相关文章:

java - 从进程中读取错误流

c# - 使用 C# 问题打开 Java 控制台

c - 无法理解以下程序中的 pthread_create() 行为?

c++ - 无法在 Linux 上使用屏幕外 OpenGL 上下文生成 mipmap

linux - 可以使用与管道命令的输出相同的输入文件吗?

shell - KornShell - 使用可能未设置的变量进行测试

linux - 从虚拟 Linux 网络设备驱动程序发送的 RX 数据包被丢弃

regex - Sed 查找/内联替换,转义一些字符

linux - 有哪些非基于 Linux 的操作系统?

java - Ktor 创建一个额外的 Java 进程