如何清除由父进程设置的子进程中的陷阱?
问题描述:
过程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中的陷阱,但它不是得到清洁d。操作系统是Linux。
答
一般来说,您可以使用trap 15
来取消信号15的陷阱。这包括在当前shell开始忽略它时将忽略信号重置为默认值。
但是,一些实验(在macOS Sierra 10.12上使用Bash 3.2.57)显示,如果信号在进程开始时被忽略(从父进程继承),则无法重置为默认处理 - 它会继续被忽略。此外,像trap ': do nothing' 15
之后的trap 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,其中中断和创建的程序内运行的程序退出信号被忽略。这也是名字来自:i
nterrupt和q
uit on
。
好的。是的,我无法控制我正在处理的问题中的父流程。因为没有其他选择,所以我必须用-9来杀死进程,因为15不会工作。 +1为iqon – bluetech