2012-12-02 22 views
7

我正在使用phing并通过ExecTask运行硒服务器。有时我需要停止运行服务器,通过杀死它的进程。获得phid中派生的exec的pid

在获取ExecTask中产生的进程的PID有没有可能性?

+0

你有没有找到一个解决方案?测试结束后,我想杀死硒服务器。 – papaiatis

回答

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 

当你要杀死你可以在另一个ExecTask称之为硒服务器:我不知道,如果在shell环境与ExecTask所做的更改留或不

pkill pid_to_kill 

。如果是,那么你可以使用$p1。用$ p1替换pid_to_kill以杀死job1。否则,您将不得不回显pid并使用其输出中的值。

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

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的信息,你正在寻找的字符串。

我希望这是类似于你正在寻找的东西。

1

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

#!bin/bash 

./path_to_executable/process_to_run & 
echo $! 

注意“&”这个发过程为背景,并允许phing继续建设项目。最后一行输出可以由phing exec任务捕获并保存到文件的pid。要保存该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="./" /> 

注:以上您可能需要预先sudo来kill命令(取决于谁拥有的过程,以及它是如何开始

可选,但值得考虑的是增加一个任务来删除。 pid.txt文件,这样可以防止任何可能的杀死错误的进程(基于陈旧的pid),你也可能希望理智地检查pid.txt文件的内容,因为在发生错误时它可能包含某些东西除了pid之外

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

0

我最终创建了一个保存已启动程序的pid的phing任务,并在您询问时停止它。它使用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" />