7

我正在使用 phing 并通过 ExecTask 运行 selenium 服务器。有时我需要通过终止其进程来停止运行服务器。

phing 是否有可能获得在 ExecTask 中生成的进程的 PID?

4

4 回答 4

3

不,ExecTask 不能直接给出衍生进程的 pid。它只能返回它的退出状态和输出。

也许您可以修改您在 ExecTask 本身中运行的命令以保存生成进程的 pid。您可以使用$!获取最新后台命令的 pid。

job1 &                     //start job1 and run in background, end command with &
p1=$!                      //stores the pid 
echo $p1                   //gives pid of job1

当你想杀死 selenium 服务器时,你可以在另一个 ExecTask 中调用它:

pkill pid_to_kill

我不确定使用 ExecTask 在 shell 环境中所做的更改是否保留。如果是,那么您可以使用$p1. 将 pid_to_kill 替换为 $p1 以终止 job1。否则,您将不得不回显 pid 并使用其输出中的值。

否则你将不得不做pgrep name_of_program。它将给出包含该名称的所有进程。然后你可以用 杀死它pkill

于 2013-06-02T19:18:33.773 回答
1

有可能,您可以使用exec命令中的第二个参数。

exec("Script To Run", $output);

第二个变量以数组格式获取当前运行脚本的输出。因此,为了从输出中显示完整且可读的文本,我将使用一个foreach循环:

exec("ifconfig", $output); // Presuming you are developing for a Linux server
foreach ($output as $outputvar) {
    echo $outputvar . "<br>"; 
}

之后,我会使用类似的方法从您要查找的字符串中strpos提取信息。$outputvar

我希望这与您正在寻找的内容相似。

于 2012-12-02T15:32:00.483 回答
1

而不是启动要从 exec 任务中终止的进程(在您的情况下为 selenium 服务器)。使用 exec 任务启动脚本(我使用 bash,但 ruby​​、python 等也可以)。此脚本将启动所需的任务并回显 pid。在下面替换您要运行的所需路径和可执行文件。

#!bin/bash

./path_to_executable/process_to_run &
echo $!

请注意“&”这会将进程发送到后台并允许 phing 继续构建您的项目。最后一行输出 pid,然后可以由 phing exec 任务捕获并保存到文件中。要保存此 pid,请将输出选项添加到 phing exec 任务:

<exec command="your_script" spawn="true" output="./pid.txt" />

output 选项会将 exec 任务的输出保存到当前目录中的 pid.txt 文件中。请注意,您可能需要 chown 这个文件(给运行 phing 的用户)以便以后读取它。

在单独的任务中,您可以从文件中读取 pid,然后使用 exec 任务终止进程。

<loadfile property="pid" file="./pid.txt" />
<exec command="kill ${pid}" dir="./" />

注意:在上面你可能需要在 kill 命令前面加上 sudo (取决于谁拥有该进程,以及它是如何启动的。

可选但值得考虑的是添加一个任务来删除 pid.txt 文件。这将防止任何杀死错误进程的可能性(基于过时的 pid)。您可能还想彻底检查 pid.txt 文件的内容,因为如果发生错误,它可能包含 pid 以外的其他内容。

虽然这可能不是最直接或最佳的解决方案,但它确实有效。

于 2013-06-29T20:46:40.650 回答
0

我最终创建了一个 phing 任务来保存已启动程序的 pid,并在您请求时停止它。它使用Cocur\BackgroundProcess在后台启动进程,也可以返回 pid。

<?php

require_once "phing/Task.php";

class BackgroundExecTask extends Task {

    protected $command = null;
    protected $executable = null;
    protected $id = null;

    protected static $pidMap = [];

    public function init() {
        if (!class_exists('\Cocur\BackgroundProcess\BackgroundProcess')) {
            throw new BuildException("This task requires the Cocur Background Process componente installed and available on the include path", $this->getLocation());
        }
    }

    public function main() {
        switch ($this->command) {
            case "start":
                return $this->start();
            case "stop":
                return $this->stop();
        }
    }

    protected function start() {
        $process = new \Cocur\BackgroundProcess\BackgroundProcess($this->executable);
        $process->run();
        // you can also return the pid
        //$this->project->setProperty($this->pidProperty, $process->getPid());
        self::$pidMap[$this->id] = $process;
    }

    protected function stop() {
        self::$pidMap[$this->id]->stop();
    }

    public function setCommand($command)
    {
        $this->command = "" . $command;
    }

    public function setExecutable($executable)
    {
        $this->executable = "" . $executable;
    }

    public function setId($id)
    {
        $this->id = "" . $id;
    }

}

用法:

<backgroundexec id="myprogram" command="start" executable="somebinary" />
<backgroundexec id="myprogram" command="stop" />
于 2015-08-25T11:45:09.893 回答