在phing中获得生成的exec的pid

时间:2012-12-02 15:27:21

标签: php linux command-line phing

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

是否有可能在ExecTask中产生进程的PID?

4 个答案:

答案 0 :(得分: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。用$ p1替换pid_to_kill以杀死job1。否则,您必须回显pid并使用其输出中的值。

否则你将pgrep name_of_program。它将为包含该名称的所有进程提供。然后你可以用pkill杀死它。

答案 1 :(得分: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中提取您要查找的字符串的信息。

我希望这与您所寻找的类似。

答案 2 :(得分:1)

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

#!bin/bash

./path_to_executable/process_to_run &
echo $!

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

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

输出选项会将exec任务的输出保存到当前目录中的pid.txt文件中。请注意,您可能需要将此文件(对于运行phing的用户)进行chown以使其能够在以后读取。

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

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

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

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

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

答案 3 :(得分: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" />