Как я могу заставить PHP-скрипт продолжить выполнение скрипта после вызова exec ()?

Я использую функцию exec в PHP для запуска команды. Команда, которую я выполняю, часто может занять довольно много времени, и мне не нужно читать ее вывод. Есть ли простой способ сказать PHP не ждать завершения команды exec, прежде чем продолжить работу с остальной частью скрипта?


person David Jones    schedule 28.09.2012    source источник
comment
возможно, сделать это как отдельный процесс?   -  person tradyblix    schedule 28.09.2012
comment
Как бы я это сделал? Могу ли я просто добавить & в конец команды?   -  person David Jones    schedule 28.09.2012
comment
exec("nohup $your_command &") - запустить команду, невосприимчивую к зависаниям, вывод на не-tty (nohup), запустить ее в фоновом режиме (&)   -  person Nemoden    schedule 28.09.2012
comment
@Nemoden: Замечательно! Спасибо. Итак, каждый раз, когда я звоню, он запускает новый процесс, верно? Есть ли аналогичный способ запустить их в отдельных потоках?   -  person David Jones    schedule 28.09.2012
comment
да, новый процесс начнется, я продемонстрирую это в ответе.   -  person Nemoden    schedule 28.09.2012


Ответы (3)


// nohup_test.php:

// a very long running process
$command = 'tail -f /dev/null';
exec("nohup $command >/dev/null 2>/dev/null &"); // here we go
printf('run command: %s'.PHP_EOL, $command);
echo 'Continuing to execute the rest of this script instructions'.PHP_EOL;

for ($x=1000000;$x-->0;) {
  for ($y=1000000;$y-->0;) {
    //this is so long, so I can do ps auwx | grep php while it's running and see whether $command run in separate process
  }
}

запустите nohup_test.php:

$ php nohup_test.php
run command: tail -f /dev/null
Continuing to execute the rest of this script instructions

Давайте узнаем pids наших процессов:

$ ps auwx | grep tail
nemoden   3397  0.0  0.0   3252   636 pts/8    S+   18:41   0:00 tail -f /dev/null
$ ps auwx | grep php
nemoden   3394 82.0  0.2  31208  6804 pts/8    R+   18:41   0:04 php nohup_test.php

как видите, pid другой, и мой скрипт выполняется, не дожидаясь tail -f /dev/null.

person Nemoden    schedule 28.09.2012
comment
Использование /dev/null было ключом к правильной работе. По какой-то причине, когда я указал фактическое местоположение файла журнала (т.е. /path/to/logfile, как было предложено @zaf), PHP все еще ждал завершения процесса. Есть идеи, почему это так? - person David Jones; 28.09.2012
comment
если вы укажете файл журнала так: exec("nohup $command >/tmp/my.log 2>/dev/null &"); и запустите php nohup_test.php, он не распечатает Continuing to execute the rest of this script instructions? Потому что он работает нормально или ... должен работать так ... В противном случае это действительно странно - person Nemoden; 11.10.2012

Вот что я использую (вы можете использовать exec или system вместо paasthru):

passthru("/path/to/program args >> /path/to/logfile 2>&1 &");
person zaf    schedule 28.09.2012
comment
Спасибо! Однако я не слишком знаком с некоторым синтаксисом здесь. Что делают >> и 2>&1 &? - person David Jones; 28.09.2012
comment
›› отправит вывод программы в файл журнала. «2› & 1 »будут перенаправлять сообщения об ошибках на стандартный вывод, в основном это означает, что весь вывод будет идти в файл журнала. '&' Означает выполнение команды в фоновом режиме. - person zaf; 28.09.2012

То, что вы ищете, называется асинхронным вызовом, как здесь:

Выполнение асинхронной оболочки в PHP

php выполняет фоновый процесс

PHP exec () как фоновый процесс (среда Windows Wampserver)

person WebChemist    schedule 28.09.2012
comment
Спасибо! Я довольно много искал это перед публикацией, но, похоже, никогда не использовал правильные ключевые слова ... - person David Jones; 28.09.2012