如何使用“system()”终止在Perl脚本中启动的命令

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

提问人:yasara malshan 提问时间:4/26/2021 更新时间:4/29/2021 访问量:449

问:

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

system("my_command");

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

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

有什么方法可以做到这一点吗?

Linux Perl的

评论


答:

4赞 Ted Lyngmo 4/26/2021 #1

system对此不是那么有用。请考虑使用 which 返回已启动子进程的进程标识符。open2

use IPC::Open2;

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

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

你现在可以继续.killwaitpid$pid

下面是一个使用一些老式 OOP 的示例,以便当您的程序退出时,您启动的所有进程都将自动编辑。我敢肯定有现成的perl包以更完整的方式封装它,但这应该给你一个大致的想法。kill

#!/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

评论

0赞 KubaFYI 2/15/2023
这实际上并没有回答关于如何终止 system() 生成的命令的问题。答案只是说不要使用 system()。
0赞 Ted Lyngmo 2/15/2023
@KubaFYI 是的,我没有尝试解释如何使用锤子拧入螺丝,而是为 OP 情况提供了一个更理智的替代方案。
0赞 KubaFYI 2/15/2023
是的,这是有道理的。我只是脾气暴躁,它没有帮助我解决必须杀死其他人编写的数千行代码中系统生成的东西的问题,现在早已不复存在哈哈
0赞 Ted Lyngmo 2/15/2023
@KubaFYI :-)设置是什么? 还是什么?也许如果你在一个新问题中以最小的可重现示例描述脚本的作用,我可以看看。最简单的方法可能是用替换调用,然后做一点魔术来跟踪所有生成的 pid - 但是,现在需要更详细一点。system("command &");systemmyspawnfork()
1赞 KubaFYI 2/15/2023
在该代码库中生成子进程可能有 5 种不同的方式,因此可能不值得在评论中讨论。感谢您的帮助!