【问题标题】:How to clear a trap in a child process which was set by a parent process?如何清除父进程设置的子进程中的陷阱?
【发布时间】:2017-02-15 20:22:49
【问题描述】:

进程 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。

【问题讨论】:

    标签: linux unix process sigkill sigterm


    【解决方案1】:

    通常,您可以使用 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
    

    这个主题作品的变化。

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

    #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 和 quit on

    【讨论】:

    • 好的。是的,在我正在处理的问题中,我无法控制父进程。我必须用 -9 终止进程,因为 15 将不起作用,因为没有其他选项。为 iqon +1
    猜你喜欢
    • 1970-01-01
    • 2011-07-10
    • 1970-01-01
    • 2018-04-11
    • 1970-01-01
    • 2016-12-28
    • 2019-05-20
    • 2023-03-13
    • 1970-01-01
    相关资源
    最近更新 更多