Есть ли способ использовать shell_exec, не дожидаясь завершения команды? - PullRequest
86 голосов
/ 20 июня 2009

У меня есть процесс с интенсивным процессом, который я хотел бы запустить в фоновом режиме.

Пользователь нажимает на страницу, запускается PHP-скрипт и, наконец, в зависимости от некоторых условий, если требуется, он должен запустить скрипт оболочки, E.G.:

shell_exec('php measurePerformance.php 47 844 email@yahoo.com');

В настоящее время я использую shell_exec , , но , для этого требуется, чтобы скрипт ожидал вывода. Есть ли способ выполнить команду, которую я хочу без ожидания ее завершения?

Ответы [ 9 ]

138 голосов
/ 20 июня 2009

Как насчет добавления.

"> /dev/null 2>/dev/null &"

shell_exec('php measurePerformance.php 47 844 email@yahoo.com > /dev/null 2>/dev/null &');

Обратите внимание, что это также избавляет от stdio и stderr.

26 голосов
/ 20 июня 2009

Это выполнит команду и отключится от запущенного процесса. Конечно, это может быть любая команда, которую вы хотите. Но для теста вы можете создать php-файл с помощью команды sleep (20).

exec("nohup /usr/bin/php -f sleep.php > /dev/null 2>&1 &");
11 голосов
/ 14 мая 2013

Вы также можете мгновенно вернуть свой вывод клиенту и продолжить обработку PHP-кода.

Это метод, который я использую для Ajax-вызовов с долгим ожиданием, который не будет иметь никакого влияния на стороне клиента:

ob_end_clean();
ignore_user_abort();
ob_start();
header("Connection: close");
echo json_encode($out);
header("Content-Length: " . ob_get_length());
ob_end_flush();
flush();
// execute your command here. client will not wait for response, it already has one above.

Подробное объяснение вы можете найти здесь: http://oytun.co/response-now-process-later

8 голосов
/ 18 февраля 2010

В Windows 2003, чтобы вызвать другой скрипт без ожидания, я использовал это:

$commandString = "start /b c:\\php\\php.EXE C:\\Inetpub\\wwwroot\\mysite.com\\phpforktest.php --passmsg=$testmsg"; 
pclose(popen($commandString, 'r'));

Это работает только ПОСЛЕ предоставления изменяющихся разрешений для cmd.exe - добавьте Чтение и Выполнение для IUSR_YOURMACHINE (я также установил запись в Запретить).

6 голосов
/ 10 февраля 2017

Конечно, для windows вы можете использовать:

$WshShell = new COM("WScript.Shell");
$oExec = $WshShell->Run("C:/path/to/php-win.exe -f C:/path/to/script.php", 0, false);

Примечание:

Если вы получили ошибку COM, добавьте расширение к вашему php.ini и перезапустите apache:

[COM_DOT_NET]
extension=php_com_dotnet.dll
6 голосов
/ 26 июня 2009

Использовать команду PHP popen, например ::100100

pclose(popen("start c:\wamp\bin\php.exe c:\wamp\www\script.php","r"));

Это создаст дочерний процесс, и сценарий будет выполнять в фоновом режиме, не ожидая вывода.

1 голос
/ 20 июня 2009

Это будет работать, но вы должны быть осторожны, чтобы не перегружать ваш сервер, потому что он будет создавать новый процесс при каждом вызове этой функции, которая будет работать в фоновом режиме. Если одновременно выполняется только один одновременный вызов, то этот обходной путь сделает эту работу.

Если нет, то я бы посоветовал запустить очередь сообщений, например, beanstalkd / gearman / amazon sqs.

1 голос
/ 20 июня 2009

Если это не веб-страница, я рекомендую генерировать какой-то сигнал (возможно, сброс файла в директорию) и поручить заданию cron выполнить работу, которую необходимо выполнить. В противном случае мы, вероятно, попадем на территорию использования pcntl_fork() и exec() изнутри процесса Apache, и это просто плохое умение.

0 голосов
/ 20 июня 2009

Вы всегда можете публиковать поверх AJAX страницу, которая вызывает shell_exec ().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...