【发布时间】:2016-03-31 04:52:58
【问题描述】:
如果我有一个像apt-cache search <some query> 这样长时间运行的system 命令,有没有办法将命令行上通过^C 发送的SIGINT 转发到父Perl 进程,这样所有子进程进程被收割。
此示例没有所需的行为。信号被发送到子进程。
#!/usr/bin/env perl
use strict;
use warnings FATAL => 'all';
use autodie;
# long running command on ubuntu, produces a ton of output.
# replace with your favorite long running command
system("apt-cache search hi");
print("Perl did not catch SIGINT even with autodie\n");
我尝试四处寻找捕获将由system("apt-cache search hi &") 创建的孩子的pid 的方法,但找不到任何方法,所以我尝试forking 和execing 进程并编写信号处理程序。这不起作用,因为apt-cache 本身通过clone 系统调用启动了一些进程。手动滚动一些逻辑来遍历部分流程树并清理
#!/usr/bin/env perl
use strict;
use warnings FATAL => 'all';
use autodie;
my $cpid;
$SIG{INT} = sub {
kill 'KILL', $cpid;
exit;
};
# long running command on ubuntu, produces a ton of output.
# replace with your favorite long running command
$cpid = fork;
if ($cpid == 0) {
exec 'apt-cache', 'search', 'hi';
}
print "Perl did not catch SIGINT even with autodie\n";
我想基本上我想要的是一种确定system 启动的子进程是否由于SIGINT 之类的信号而退出的方法,这样我就可以让 Perl 脚本自行清理,或者是一种行走的方法子进程并以这样的方式收获它们,从而干净且可移植地处理奇怪的进程管理边缘情况。
【问题讨论】:
-
IPC::Run可能是您需要的,而不是系统。或者,只需将SIGCHLD设置为“IGNORE”,这样它们就会在退出时自动收割。 -
这是一种检测命令是否被用户中止的方法:见Name of signal number 2
标签: perl