包装器脚本应将哪些信号传递给子程序?

发布于 2024-07-13 11:29:21 字数 1409 浏览 4 评论 0原文

如果我有一个脚本是另一个程序的包装器(例如,守护程序包装器或< a href="https://stackoverflow.com/questions/148057/calling-a-math">mathematica 的包装器),有时在包装器程序中捕获信号并将其传递给子程序。 例如,这里有一些处理 INT(中断)信号的 Perl 代码,这样如果您在启动包装器后执行 ctrl-C,子程序也会被中断:

my $subprogram = "foo args";
my $pid = open(F, "$subprogram |") or die "Can't open pipe from $subprogram: $!";
$SIG{INT} = sub { kill('INT', $pid); 
                  close(F); 
                  die "Passed along INT signal and now aborting.\n"; };
print while(<F>);
close(F);

[所有可能的信号](http://en.wikipedia.org/wiki/Signal_(computing) 程序可能处理的内容,哪些内容应该处理传递包装脚本?
一个好的包装纸还应该做些什么吗?

编辑:最初这个问题是问如何传递所有可能的信号。 感谢最初的答案,我了解到这不是正确的问题。

编辑:我弄清楚是什么让我在这里陷入困境。 Mathematica 显然与其父进程分离。 所以我必须明确地传递各种终止信号:

$SIG{INT} =  sub { kill('INT', $pid); };  # pass along SIGINT (eg, ctrl-C)
$SIG{TERM} = sub { kill('TERM', $pid); }; # pass along SIGTERM (kill's default)
$SIG{QUIT} = sub { kill('QUIT', $pid); }; # pass along SIGQUIT
$SIG{ABRT} = sub { kill('ABRT', $pid); }; # pass along SIGABRT
$SIG{HUP} =  sub { kill('HUP', $pid); };  # pass along SIGHUP

通常这不是必需的,因为子进程会自动获取传递的这些信号(感谢让我直接了解这一点的答案!)。 所以现在我想知道为什么(以及如何)mathematica 分离出来......

If I have a script that is a wrapper for another program (e.g., a daemonizer wrapper or a wrapper for mathematica), it is sometimes useful to trap signals in the wrapper program and pass them along to the subprogram.
For example, here's some Perl code to deal with the INT (interrupt) signal so that if you do ctrl-C after launching the wrapper the subprogram also gets interrupted:

my $subprogram = "foo args";
my $pid = open(F, "$subprogram |") or die "Can't open pipe from $subprogram: $!";
$SIG{INT} = sub { kill('INT', $pid); 
                  close(F); 
                  die "Passed along INT signal and now aborting.\n"; };
print while(<F>);
close(F);

Of [all the possible signals](http://en.wikipedia.org/wiki/Signal_(computing) that a program might handle, which ones should a wrapper script pass along?
Is there anything else that a good wrapper should do?

EDIT: Originally this question was asking how to pass along all possible signals. Thanks to the initial answers I learned that was not the right question.

EDIT: I figured out what threw me for a loop here. Mathematica apparently detaches itself from its parent process. So I have to pass along various termination signals explicitly:

$SIG{INT} =  sub { kill('INT', $pid); };  # pass along SIGINT (eg, ctrl-C)
$SIG{TERM} = sub { kill('TERM', $pid); }; # pass along SIGTERM (kill's default)
$SIG{QUIT} = sub { kill('QUIT', $pid); }; # pass along SIGQUIT
$SIG{ABRT} = sub { kill('ABRT', $pid); }; # pass along SIGABRT
$SIG{HUP} =  sub { kill('HUP', $pid); };  # pass along SIGHUP

Normally this would not be necessary as child processes automatically get these signals passed along (thanks for the answers that set me straight on this!). So now I'm wondering why (and how) mathematica detaches itself...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

狼性发作 2024-07-20 11:29:22

没有任何。

无论如何,您可能在键盘上生成的信号都会发送到子进程,除非子进程采取措施避免这种情况(在这种情况下,您有什么资格干涉)。

可能杀死父进程的其他信号通常会导致子进程在下次写入父进程死亡时关闭的管道时消失。

因此,除非您有理由认为子进程对信号管理不善,否则我不会担心向子进程转发任何信号。 如果孩子对信号处理不当,也许你应该修复孩子而不是黑掉父母。

None.

The signals that you might generate at the keyboard are sent to the child process anyway, unless the child takes steps to avoid that (in which case, who are you to interfere).

The other signals that might kill the parent process would normally cause the child to disappear when it next writes to the pipe that was closed when the parent died.

So, unless you have reason to think that the child process mismanages signals, I would not worry about relaying any signals to the child. And if the child mismanages signals, maybe you should fix the child rather than hack the parent.

孤檠 2024-07-20 11:29:22

我真的不明白你为什么要这么做。 就此而言,我不明白您为什么要向包装器脚本发送信号。

ETA:停止和重新启动信号发送到整个进程组。 如果这就是您所追求的:只需确保您的子进程是该进程组的一部分(默认情况下是这样)。

预计到达时间2:
如果 mathematica 确实自行分离(可以使用 setsid()setpgid() 来完成),这意味着它明确不想接收此类信号,因此您应该'不要发送它们:它可能无论如何也不会处理它们。

I really don't see why you would want to do that. For that matter, I don't see why you would want to send signals to the wrapper script.

ETA: Stop and restart signals are sent to the whole process group. If that's what you're after: just make sure your child process is part of that process group (it is by default AFAIK).

ETA2:
If mathematica really detaches itself (which can be done using setsid() and setpgid()), that means it explicitly does not want to receive such signals, so you shouldn't send them: it probably won't handle them anyway.

归属感 2024-07-20 11:29:22

您可以使用键 %SIG 获取所有信号的列表。 因此,为了将它们全部传递出去,您可以设置处理程序来向子进程 ID 发送信号:

for my $signal (keys %SIG) {
    $SIG{$signal} = sub { kill($signal, $child_pid); };
}

您可能需要本地化 %SIG

我并不是说这是一个好主意,而是说这是如何做到的。

You can get a list of all signals with keys %SIG. So, to pass them all through, you set handlers to send the signal the child process ID:

for my $signal (keys %SIG) {
    $SIG{$signal} = sub { kill($signal, $child_pid); };
}

You'll probably want to localize %SIG.

Not that I'm saying it's a good idea, but that's how to do it.

一抹苦笑 2024-07-20 11:29:21

有很多信号如果以这种方式“通过”是很危险的。 “man 7 signal”并查看 SIGPIPE、SIGILL、SIGCHILD 等内容。很可能您只是不想碰这些家伙。

因此,真正的问题是:您正在寻找的行为是什么? 我敢打赌您真正想要的是 SIGINT & SIGCONT 将传递给子进程。 该子程序是否对其他信号(例如 HUP、USR1 或 USR2)执行任何奇特的操作?

我想您真的只是对 SIGINT & 感兴趣。 SIGCONT 和其余的(即 SIGSEGV、SIGKILL 等)将自行处理,因为父进程终止也会清理子进程。

哦,顺便说一句,你的例子:

print while(<F>);

很好,如果父 perl 进程被挂起,它不会继续从 F 读取,一旦管道填满,你的子程序将阻止写入 stdout,这可能很漂亮也有很多你想要的行为。

对于一些更有趣的想法,请查看“man bash”和内置的“trap”,看看 shell 开发人员为解决这个问题做了什么。

There are many signals that would be dangerous to just "pass through" in this way. "man 7 signal" and look at things like SIGPIPE, SIGILL, SIGCHILD, etc. It's very likely that you just don't want to touch those guys.

So, the real question becomes: What is the behavior you're looking for? I bet all you really want is SIGINT & SIGCONT to be passed through to the child. Does the subprogram do anything fancy with other signals, like HUP, USR1, or USR2?

I presume you're really just interested in SIGINT & SIGCONT, and the rest (i.e. SIGSEGV, SIGKILL, etc.) will take care of themselves, as the parent process termination will clean up the child as well.

Oh, and by the way, your example of:

print while(<F>);

Is fine, and if the parent perl process is suspended, it won't continue reading from F, once that pipe fills up, your subprogram will block writing into stdout, which is probably pretty much the behavior you want as well.

For some more interesting thoughts, take a look at "man bash" and the "trap" builtin to see what the shell developers have done to help this problem.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文