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 № 1Jednym 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.