2011-12-08 63 views
1

您好我将如何退出在Linux机器上使用qx //在perl中启动的已完成的进程?在Perl中启动的退出进程

我正在考虑调用ps来查找PID并调用kill来退出。但我想知道是否有更简单的方法来做到这一点。

感谢

+0

你做我的'$ S = QX/some_command /;'你的Perl脚本,你想手动杀'some_command'使你的脚本可以相处吗? –

+0

是的,这是我想要做的。我有一个我正在调用的Java Jar,我想在完成处理后立即退出它。 – urbanspr1nter

+1

但是'qx //'在进程退出时立即返回,并且当完成时您的jar应该退出。除非卡住,否则不应该杀死'qx //'进程。我错过了什么? –

回答

1

你可以使用

pkill -o -u urbanspr1nter -f some_command 

pgrep ... | xargs ps代替pkill先审查。

+0

您不能在Perl脚本中运行它,因为脚本阻塞直到过程结束。但是,如果从shell运行,它将工作。 – Jonathan

+0

@Jonathan:不错,谢谢。从我的答案中删除它。 – flesk

+0

谢谢,这个工程! – urbanspr1nter

4

如果它与qx//一起启动并且已经完成,则不需要杀死它,它已经消失。我怀疑你的实际上可能会卡住:没有完成流程明智的,但没有做任何有用的东西了。

没有任何东西可以直接从操作的Perl端执行。 qx//是一个同步呼叫。它期望它启动的进程终止,它唯一的返回码是进程的标准输出转储。 (勉强,也通过$?返回代码)

它不是为了产生后台进程。因此,它不允许您访问孩子的PID,更不用说控制工作。

所以你的情况,如果是一次性的问题,你只需要找到并通过psgrepkillpgreppkill适合你的思维最好的方式组合的任何终止错误的过程。如果这是一个经常出现的问题,那么您应该从内建qx//设施迁移到一些能让您更好控制的设施。例如,IPC::Run提供超时。

3

我认为real你想问的问题是“我如何在后台启动一个进程(以后可能会杀掉它)?”

最简单的解决方案是open来自过程的管道。因此,而不是

my $output = qx/some_command/; 
# do something with $output 

你会做

my $pid = open my $pipe, "some_command |" or die $!; 
while (my $line = <$pipe>) { 
    # do something with $line 
    last if some_condition(); 
} 
close $pipe or $! and die $!; 

如果close的子进程结束前的管道,它会尝试输出不同的是,下一次会收到一个SIGPIPE信号,这将通常会杀死它。如果您怀疑该流程可能会继续运行而没有会产生任何输出,您可以kill手动使用它。

kill $pid, 1; # 1 == SIGHUP on most Unix systems 

(你应该关闭的管道,因为close将等待进程结束做到这一点之前。)

但请注意,如果找不到Perl不得不调用一个shell来解析您的命令,由open返回的进程ID将是shell的进程ID,而不是实际的命令。您可以通过使用open多参数形式避免这种情况:

my $pid = open my $pipe, '-|', $command, @command_args or die $!;