我试图按名称杀死进程,我将作为变量传递给系统命令。
以下是我所拥有的:
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]
但是,如果我直接在系统命令中输入进程名称,它就可以工作。
有人可以帮我吗?
答案 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。