/ / Detectar comando ejecutándose en segundo plano - exec, php

Comando de detección que se ejecuta en segundo plano - exec, php

Estoy usando PHP y su interfaz de línea de comandos paraejecutar un script. Durante la ejecución del script, invoco algunos comandos en segundo plano (algunos de los cuales consumen bastante tiempo), usando el siguiente código de php.net:

function execInBackground($cmd) {
if (substr(php_uname(), 0, 7) == "Windows"){
pclose(popen("start /B ". $cmd, "r"));
}
else {
exec($cmd . " > /dev/null &");
}
}

El script principal puede ser llamado un par de veces antes de que todos los comandos se hayan ejecutado completamente.

¿Hay alguna forma de verificar antes de ejecutar el comando si ya se está ejecutando en segundo plano desde una ejecución anterior del script?

Respuestas

1 para la respuesta № 1

Una forma de hacer un seguimiento del fondocomandos es almacenar la información en un archivo en algún lugar. Es posible que el nombre del comando no sea único en todo el sistema, por lo que no puede verificarlo. Puede almacenar la ID del proceso en un archivo de configuración y verificar el comando por una cadena:

function execInBackground($cmd)
{
$running = false;

// get the state of our commands
$state = json_decode(file_get_contents("state.json"));

// check if the command we want to run is already running and remove commands that have ended
for ($i = 0; $i < count($state->processes); $i++)
{
// check if the process is running by the PID
if (!file_exists("/proc/" . $state->processes[$i]->pid))
{
// this command is running already, so remove it from the list
unset($state->processes[$i]);
}

else if ($cmd === $state->processes[$i]->command)
{
$running = true;
}
}

// reorder our array since it"s probably out of order
$state->processes = array_values($state->processes);

// run the command silently if not already running
if (!$running)
{
$process = proc_open($cmd . " > /dev/null &", array(), $pipes);
$procStatus = proc_get_status($process);

$state->processes[] = array("command" => $cmd, "pid" => $procStatus["pid"]);
}

// save the new state of our commands
file_put_contents("state.json", json_encode($state));
}

El archivo de configuración se vería así:

{
"processes": [
{
"command": "missilecomm launch -v",
"pid": 42792
}
]
}

(Soy de la "persuasión" de JSON, pero puedes usar el formato que quieras;))

Esto no funcionaría si a veces quería ejecutar la misma cadena de comandos más de una vez.

Por como execInBackground() borra los comandos terminados, solo funcionaría en Linux. Tendría que encontrar otra forma de verificar si existe una ID de proceso en Windows. Este código no se ha probado, y no estoy seguro de si mi proc_* Las llamadas son correctas, tampoco.