gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-04 18:36:08 26 4
gpt4 key购买 nike

如果我有一个长期运行 system命令如 apt-cache search <some query> , 有没有办法转发 SIGINT通过 ^C 发送在命令行到父 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 &") 创建的 child 的 pid 的方法。 ,但找不到,所以我尝试了 fork ing 和 exec处理进程并编写信号处理程序。这不起作用,因为 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 脚本在其自身之后进行清理,或者以一种方式来处理子进程并以一种方式处理它们,从而干净且可移植地处理进程管理的奇怪边缘情况。

最佳答案

让 child 成为一个进程组的头,然后向整个进程组发送信号。

#!/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', 'search', 'hi';
}

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

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

关于Perl 将 SIGINT 从 `system` 命令转发到父进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34457955/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com