从perl脚本中删除一个进程

bla*_*ury 3 perl pid system kill

我试图通过名称杀死进程,我将作为变量传递给系统命令.

以下是我所拥有的:

my $processName=$ARGV[0];
print "$processName\n";
system(q/kill -9 `ps -ef | grep '$processName' | grep -v grep | awk '{print $2}'`/);
Run Code Online (Sandbox Code Playgroud)

上面的脚本抛出一个错误:

kill: usage: kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]
Run Code Online (Sandbox Code Playgroud)

但是,如果我直接在系统命令中输入进程名称,它就可以工作.

有人可以帮我吗?

zdi*_*dim 9

一个问题是,调用脚本的命令行具有您根据设计查询的进程的名称; 所以发现一件事就是剧本本身.

这可以防范,但为什么要去那个大管道的系统?

在Perl中查询进程,例如使用Proc :: ProcessTable

use warnings;
use strict;
use Proc::ProcessTable;

my $proc_name = shift // die "Usage: $0 process-name\n";  #/

my $pid;
my $pt = Proc::ProcessTable->new();
foreach my $proc (@{$pt->table}) {
    next if $proc->cmndline =~ /$0.*$proc_name/;  # not this script
    if ($proc->cmndline =~ /\Q$proc_name/) {
        $pid = $proc->pid;
        last;
    }   
}

kill 9, $pid;                    # must it be 9 (SIGKILL)? 
my $gone_pid = waitpid $pid, 0;  # then check that it's gone
Run Code Online (Sandbox Code Playgroud)

请注意,通过发送SIGTERM(通常是15)来"杀死"进程要好得多,而不是SIGKILL.

寻找进程"名称"可能是危险的,因为有许多进程在可能包含该单词的现代系统上运行长命令行.代码使用您的要求,只需按提交的名称查询,但我建议通过额外的检查加强.

对于模块可以查询的许多进程详细信息,请查看其存根模块.

即使您更愿意自己解析进程表,我也只能ps -ef在脚本中解析它.这为确保您真正终止所需内容提供了更大的灵活性.