加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Perl从`system`命令转发SIGINT到父进程

发布时间:2020-12-16 06:26:41 所属栏目:大数据 来源:网络整理
导读:如果我有一个长时间运行的系统命令,如apt-cache search some query,有没有办法将命令行上通过^ C发送的SIGINT转发到父Perl进程,以便所有子进程都是收获. 此示例没有所需的行为.信号被发送到子进程. #!/usr/bin/env perluse strict;use warnings FATAL = 'all
如果我有一个长时间运行的系统命令,如apt-cache search< some query>,有没有办法将命令行上通过^ 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 autodien");

我试图寻找捕获将由系统创建的孩子的pid的方法(“apt-cache search hi&”),但找不到任何东西,所以我尝试分叉并执行该过程并写入信号处理程序.这不起作用,因为apt-cache本身通过克隆系统调用启动了一些进程.手动滚动一些逻辑来遍历流程树的一部分并清理它

#!/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 autodien";

我想基本上我想要的是一种确定系统启动的子进程是否由于SIGINT之类的信号退出的方式,所以我可以让Perl脚本自行清理,或者一种方式来处理子进程并将其收入一种可以干净利落地处理流程管理的奇怪边缘情况的方法.

解决方法

让孩子成为进程组的负责人,然后将信号发送给整个进程组.

#!/usr/bin/perl

use strict;
use warnings;
use autodie;

use POSIX qw( setpgid );

my $child_pid;

$SIG{INT} = sub {
    kill INT => -$child_pid if $child_pid;
    exit(0x80 | 2);  # 2 = SIGINT
};

my $child_pid = fork();
if (!$child_pid) {
    setpgid($$);
    exec 'apt-cache','hi';
}

WAIT: {
   no autodie;
   waitpid($child_pid,0);
   redo WAIT if $? == -1 and $!{EINTR};
   die $! if $? == -1;
}

exit( ( $? >> 8 ) | ( 0x80 | ( $? & 0x7F ) ) );

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读