从perl脚本中删除一个进程

时间:2018-03-20 08:25:02

标签: perl system pid kill

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

以下是我所拥有的:

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

上面的脚本会抛出错误:

kill: usage: kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]

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

有人可以帮我吗?

4 个答案:

答案 0 :(得分:7)

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

这可以防范,但为什么要使用那个大管道进入系统呢?

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

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

my $proc_name = shift @ARGV or 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

请注意,杀死"更好。通过发送SIGTERM(通常为15),而不是SIGKILL来发送流程。

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

对于模块可以查询的许多流程详细信息,请参阅其stub module

即使您自己解析流程表,我只会得到ps -ef,然后在脚本中解析它。这为确保您真正终止所需内容提供了更大的灵活性。

答案 1 :(得分:2)

您有不同的变量$processName$jobName,因此整个` `表达式最终为空。 use strict会指出这一点;它甚至对于三行脚本也很有用。 kill错误消息是您在没有任何参数的情况下运行它时获得的消息。

专业提示:pkill存在,您可以使用一个命令替换整个有问题的黑客。

答案 2 :(得分:0)

my $pid = `ps -ef | grep '$processName' | grep -v grep | awk '{print \$2}'`;
print $pid;
system("kill -9 $pid");

这个有用!!!

答案 3 :(得分:0)

您可以按名称终止进程,而无需使用IPC::System::Simple调用shell:

use IPC::System::Simple qw(systemx EXIT_ANY);
systemx(EXIT_ANY, 'pkill', '-9', '--', $processName);

或者您可以先收集进程ID列表:

use IPC::System::Simple qw(capturex EXIT_ANY);
kill 9, capturex(EXIT_ANY, 'pgrep', '--', $processName));

然后你不必担心String::ShellQuote。请参阅daxim的this answer