2012-12-02 50 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" />