/ / Wykryj polecenie działające w tle - exec, php

Wykryj polecenie działające w tle - exec, php

Korzystam z php i jego interfejsu wiersza poleceńwykonać skrypt. Podczas wykonywania skryptu wywołuję niektóre polecenia w tle (niektóre z nich są dość czasochłonne), używając następującego kodu z php.net:

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

Skrypt główny może zostać wywołany kilka razy, zanim wszystkie polecenia zostaną całkowicie wykonane.

Czy istnieje sposób, aby sprawdzić przed wykonaniem polecenia, czy jest ono już uruchomione w tle po poprzednim wykonaniu skryptu?

Odpowiedzi:

1 dla odpowiedzi № 1

Jednym ze sposobów śledzenia tłapolecenie służy do przechowywania informacji w jakimś pliku. Nazwa polecenia może nie być unikalna w całym systemie, więc nie możesz tego sprawdzić. Możesz zapisać identyfikator procesu w pliku konfiguracyjnym i sprawdzić polecenie poprzez ciąg znaków:

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));
}

Plik konfiguracyjny wyglądałby mniej więcej tak:

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

(Jestem z „perswazji” JSON, ale możesz użyć dowolnego formatu;))

To by nie działało, jeśli ty czasami chciał uruchomić ten sam ciąg poleceń więcej niż raz.

Z powodu jak execInBackground() usuwa gotowe polecenia, działałoby to tylko w systemie Linux. Trzeba będzie znaleźć inny sposób, aby sprawdzić, czy identyfikator systemu istnieje w systemie Windows. Ten kod nie jest testowany i nie jestem pewien, czy mój proc_* połączenia są również poprawne.