我正在使用 phing 并通过 ExecTask 运行 selenium 服务器。有时我需要通过终止其进程来停止运行服务器。
phing 是否有可能获得在 ExecTask 中生成的进程的 PID?
我正在使用 phing 并通过 ExecTask 运行 selenium 服务器。有时我需要通过终止其进程来停止运行服务器。
phing 是否有可能获得在 ExecTask 中生成的进程的 PID?
不,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
命令中的第二个参数。
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
我希望这与您正在寻找的内容相似。
而不是启动要从 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 以外的其他内容。
虽然这可能不是最直接或最佳的解决方案,但它确实有效。
我最终创建了一个 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" />