【发布时间】:2012-11-20 04:15:27
【问题描述】:
我正在使用 phing 并通过 ExecTask 运行 selenium 服务器。有时我需要通过终止其进程来停止运行服务器。
phing 是否有可能获取 ExecTask 中生成的进程的 PID?
【问题讨论】:
-
您找到解决方案了吗?测试运行后,我也想杀死 selenium 服务器。
标签: php linux command-line phing
我正在使用 phing 并通过 ExecTask 运行 selenium 服务器。有时我需要通过终止其进程来停止运行服务器。
phing 是否有可能获取 ExecTask 中生成的进程的 PID?
【问题讨论】:
标签: php linux command-line phing
不,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杀死它。
【讨论】:
而不是启动要从 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" />
输出选项会将 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 以外的其他内容。
虽然这可能不是最直接或最佳的解决方案,但它确实有效。
【讨论】:
有可能,您可以在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 中提取您要查找的字符串的信息。
我希望这与您正在寻找的内容相似。
【讨论】:
我最终创建了一个 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" />
【讨论】: