我正在使用phing并通过ExecTask运行selenium服务器。有时我需要通过终止其进程来停止运行服务器。
是否有可能在ExecTask中产生进程的PID?
答案 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" />