如何以编程方式在启动它的同一脚本中终止 运行 进程?
How can I programmatically terminate a running process in the same script that started it?
如何以允许我终止进程的方式从脚本启动进程?
基本上,我可以很容易地终止主脚本,但是终止这个主脚本启动的外部进程一直是个问题。我疯狂地搜索 Perl 6 解决方案。我正要 post 我的问题然后想我会打开这个问题以使用其他语言的解决方案。
使用 Perl 6 可以轻松启动外部进程:
my $proc = shell("possibly_long_running_command");
shell
returns 进程完成后的进程对象。所以,我不知道如何以编程方式找出 运行 进程的 PID,因为变量 $proc
甚至在外部进程完成之前都没有创建。 (旁注:完成后,$proc.pid
returns 一个未定义的 Any
,所以它没有告诉我它曾经有什么 PID。)
下面是一些代码,展示了我创建 "self destructing" 脚本的一些尝试:
#!/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
顺便说一句,根据 top
.
,sleep
的 PID 也不同(即 30437
)
我也不确定如何使用 Proc::Async
进行这项工作。与 shell
的结果不同,它创建的异步进程对象没有 pid
方法。
我最初是在寻找 Perl 6 解决方案,但我对 Python、Perl 5、Java 或任何与 "shell" 交互的语言的解决方案持开放态度相当不错。
在 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 可执行文件并将命令设置为参数。
既不是 Perl、Perl 6,也不是 Java,而是 bash
:
timeout 5 bash -c "echo hello; sleep 10; echo goodbye" &
对于 Perl 6,似乎有 Proc::Async 模块
Proc::Async allows you to run external commands asynchronously, capturing standard output and error handles, and optionally write to its standard input.
# 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")
Sends a signal to the running program. The signal can be a signal name ("KILL" or "SIGKILL"), an integer (9) or an element of the Signal enum (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
有一个方法可以终止进程。
如何以允许我终止进程的方式从脚本启动进程?
基本上,我可以很容易地终止主脚本,但是终止这个主脚本启动的外部进程一直是个问题。我疯狂地搜索 Perl 6 解决方案。我正要 post 我的问题然后想我会打开这个问题以使用其他语言的解决方案。
使用 Perl 6 可以轻松启动外部进程:
my $proc = shell("possibly_long_running_command");
shell
returns 进程完成后的进程对象。所以,我不知道如何以编程方式找出 运行 进程的 PID,因为变量 $proc
甚至在外部进程完成之前都没有创建。 (旁注:完成后,$proc.pid
returns 一个未定义的 Any
,所以它没有告诉我它曾经有什么 PID。)
下面是一些代码,展示了我创建 "self destructing" 脚本的一些尝试:
#!/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
顺便说一句,根据 top
.
sleep
的 PID 也不同(即 30437
)
我也不确定如何使用 Proc::Async
进行这项工作。与 shell
的结果不同,它创建的异步进程对象没有 pid
方法。
我最初是在寻找 Perl 6 解决方案,但我对 Python、Perl 5、Java 或任何与 "shell" 交互的语言的解决方案持开放态度相当不错。
在 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 可执行文件并将命令设置为参数。
既不是 Perl、Perl 6,也不是 Java,而是 bash
:
timeout 5 bash -c "echo hello; sleep 10; echo goodbye" &
对于 Perl 6,似乎有 Proc::Async 模块
Proc::Async allows you to run external commands asynchronously, capturing standard output and error handles, and optionally write to its standard input.
# 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")
Sends a signal to the running program. The signal can be a signal name ("KILL" or "SIGKILL"), an integer (9) or an element of the Signal enum (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
有一个方法可以终止进程。