简体   繁体   English

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

[英]How can I programmatically terminate a running process in the same script that started it?

How do I start processes from a script in a way that also allows me to terminate them? 如何以允许我终止它们的方式从脚本启动进程?

Basically, I can easily terminate the main script, but terminating the external processes that this main script starts has been the issue. 基本上,我可以轻松地终止主脚本,但终止此主脚本启动的外部进程一直是个问题。 I googled like crazy for Perl 6 solutions. 我用疯狂搜索Perl 6解决方案。 I was just about to post my question and then thought I'd open the question up to solutions in other languages. 我正准备发布我的问题然后认为我会用其他语言解决问题。

Starting external processes is easy with Perl 6: 使用Perl 6可以轻松启动外部流程:

my $proc = shell("possibly_long_running_command");

shell returns a process object after the process finishes. shell在进程完成后返回一个进程对象。 So, I don't know how to programmatically find out the PID of the running process because the variable $proc isn't even created until the external process finishes. 所以,我不知道如何以编程方式找出正在运行的进程的PID,因为在外部进程完成之前甚至不创建变量$proc (side note: after it finishes, $proc.pid returns an undefined Any , so it doesn't tell me what PID it used to have.) (旁注:完成后, $proc.pid返回一个未定义的Any ,所以它不会告诉我它曾经有过什么PID。)

Here is some code demonstrating some of my attempts to create a "self destructing" script: 以下是一些代码,展示了我创建“自毁”脚本的一些尝试:

#!/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";

This results in the following output which kills the main script, but not the externally created process (see output after the word Terminated ): 这会导致以下输出Terminated主脚本,但不会导致外部创建的进程(请参阅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

By the way, the PID of sleep was also different (ie 30437 ) according to top . 顺便说一句,根据topsleep的PID也是不同的(即30437 )。

I'm also not sure how to make this work with Proc::Async . 我也不确定如何使用Proc::Async来完成这项工作。 Unlike the result of shell , the asynchronous process object it creates doesn't have a pid method. shell的结果不同,它创建的异步进程对象没有pid方法。

I was originally looking for a Perl 6 solution, but I'm open to solutions in Python, Perl 5, Java, or any language that interacts with the "shell" reasonably well. 我最初在寻找Perl 6解决方案,但我对Python,Perl 5,Java或任何与“shell”相互作用的语言的解决方案持开放态度。

For Perl 6, there seems to be the Proc::Async module 对于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. 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.";

Method kill: 方法杀死:

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). 信号可以是信号名称(“KILL”或“SIGKILL”),整数(9)或信号枚举的元素(Signal :: SIGKILL)。

An example on how to use it: 关于如何使用它的示例:

#!/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';

As you can see, $proc has a method to kill the process. 如您所见, $proc有一种方法来终止进程。

既不是Perl,Perl 6,也不是Java,而是bash

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

In Java you can create a process like this: 在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();
}

Or you can use process.destroyForcibly(); 或者你可以使用process.destroyForcibly(); , see the Process documentation for more info. ,有关详细信息,请参阅流程文档

To execute a bash command point to the bash executable and set the command as a parameter. 执行bash命令指向bash可执行文件并将命令设置为参数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM