如何使用 'system()' 终止在 perl 脚本中启动的命令

how to terminate a command that has started in a perl script, using 'system()'

我已经编写了一个 Perl 脚本来 运行 通过脚本给定的一些命令。

system("my_command");

运行安装我的 Perl 脚本后,“my_command”在 Linux 终端上正常启动。后来,我使用 'ctrl+z; kill %%' 杀死了我的脚本。但是“my_command”仍然是 运行ning。我再次尝试 'kill %%' 几次,但“my_command”没有终止。 (“my_command”是另一个正常工作的 Perl 脚本)。

我需要的是,如果我终止初始 Perl script/runner,那么所有使用 'system()' 启动的命令都应该终止。

有什么办法可以实现吗?

system 对此用处不大。考虑使用 open2,其中 returns 已启动子进程的进程标识符。

use IPC::Open2;

# A system() like call using open2():

my $pid = open2('>&STDOUT', '<&STDIN', @CommandLine);

您现在可以在 $pidkillwaitpid

这是一个使用一些老式 OOP 的示例,这样当您的程序退出时,您启动的所有进程都会自动 killed。我确信已经有现成的 perl 包以更完整的方式封装了它,但这应该给你一个大概的想法。

#!/usr/bin/perl

use strict;
use warnings;

package mysystem;

use IPC::Open2;

sub new {
    my $class=shift;

    bless {
        'pid' => open2('>&STDOUT', '<&STDIN', @_)
    }, $class;
}

sub DESTROY {
    my $self = shift;
    $self->kill(15);  # or whatever signal you want to send to it
    $self->wait;
    print "DEBUG PRINTOUT: DONE\n";
}

sub wait {
    # wait for the process to terminate
    my $self = shift;
    waitpid($self->{pid}, 0);
}

sub kill {
    # send a signal to the process
    my ($self, $signal) = @_;
    kill($signal, $self->{pid});
}

sub alive {
    # check if the process is alive
    my $self = shift;
    $self->kill(0) == 1;
}

sub run {
    # do like system(), start a sub process and wait for it
    my $sys = new(@_);
    $sys->wait;
}

package main;

sub handler {
    print "Caught signal @_ - exiting\n";
    exit(0);
}

$SIG{INT} = \&handler;

my $proc = mysystem->new('sleep', '1000');
print "Pid ". $proc->{pid} . " is " . ($proc->alive()?"alive":"dead") . "\n";

print "Letting the destructor kill it\n";

可能的输出:

Pid 3833402 is alive
Letting the destructor kill it
DEBUG PRINTOUT: DONE