如何以编程方式在启动它的同一脚本中终止正在运行的进程?

时间:2016-04-06 13:06:44

标签: java python bash perl perl6

如何以允许我终止脚本的方式从脚本启动进程?

基本上,我可以轻松地终止主脚本,但终止此主脚本启动的外部进程一直是个问题。我用疯狂搜索Perl 6解决方案。我正准备发布我的问题然后认为我会用其他语言解决问题。

使用Perl 6可以轻松启动外部流程:

my $proc = shell("possibly_long_running_command");

shell在进程完成后返回一个进程对象。所以,我不知道如何以编程方式找出正在运行的进程的PID,因为在外部进程完成之前甚至都没有创建变量$proc。 (旁注:完成后,$proc.pid会返回一个未定义的Any,因此它不会告诉我它曾经使用过什么PID。)

以下是一些代码,展示了我创建“自毁”脚本的一些尝试:

#!/bin/env perl6

say "PID of the main script: $*PID";

# limit run time of this script
Promise.in(10).then( {
    say "Took too long! Killing job with PID of $*PID";
    shell "kill $*PID"
} );

my $example = shell('echo "PID of bash command: $$"; sleep 20; echo "PID of bash command after sleeping is still $$"');

say "This line is never printed";

这会导致以下输出终止主脚本,但不会导致外部创建的进程(请参阅单词Terminated后面的输出):

[prompt]$ ./self_destruct.pl6
PID of the main script: 30432
PID of bash command: 30436
Took too long! Killing job with PID of 30432
Terminated
[prompt]$ my PID after sleeping is still 30436

顺便说一句,根据sleep30437的PID也不同(即top)。

我也不确定如何使用Proc::Async来完成这项工作。与shell的结果不同,它创建的异步流程对象没有pid方法。

我最初在寻找Perl 6解决方案,但我对Python,Perl 5,Java或任何与“shell”相互作用的语言的解决方案持开放态度。

3 个答案:

答案 0 :(得分:8)

对于Perl 6,似乎有Proc::Async模块

  

Proc :: Async允许您异步运行外部命令,捕获标准输出和错误句柄,并可选择写入其标准输入。

# command with arguments
my $proc = Proc::Async.new('echo', 'foo', 'bar');

# subscribe to new output from out and err handles:
$proc.stdout.tap(-> $v { print "Output: $v" });
$proc.stderr.tap(-> $v { print "Error:  $v" });

say "Starting...";
my $promise = $proc.start;

# wait for the external program to terminate
await $promise;
say "Done.";

方法杀死:

kill(Proc::Async:D: $signal = "HUP")
  

向正在运行的程序发送信号。信号可以是信号名称(“KILL”或“SIGKILL”),整数(9)或信号枚举的元素(Signal :: SIGKILL)。

如何使用它的示例:

#!/usr/bin/env perl6
use v6;

say 'Start';
my $proc = Proc::Async.new('sleep', 10);

my $promise= $proc.start;
say 'Process started';
sleep 2;
$proc.kill;
await $promise;
say 'Process killed';

如您所见,$proc有一种杀死进程的方法。

答案 1 :(得分:5)

Perl,Perl 6和Java,但bash

 timeout 5 bash -c "echo hello; sleep 10; echo goodbye" &

答案 2 :(得分:3)

在Java中,您可以创建一个这样的过程:

ProcessBuilder processBuilder = new ProcessBuilder("C:\\Path\program.exe", "param1", "param2", "ecc...");
Process process = processBuilder.start(); // start the process

process.waitFor(timeLimit, timeUnit); // This causes the current thread to wait until the process has terminated or the specified time elapses

// when you want to kill the process
if(process.isAlive()) {
    process.destroy();
}

或者您可以使用process.destroyForcibly();,有关详细信息,请参阅Process documentation

执行bash命令指向bash可执行文件并将命令设置为参数。