Есть ли способ использовать shell_exec, не дожидаясь завершения команды?

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

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

shell_exec('php measurePerformance.php 47 844 [email protected]');

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

Ответ 1

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

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

shell_exec('php measurePerformance.php 47 844 [email protected] > /dev/null 2>/dev/null &');

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

Ответ 2

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

exec("nohup /usr/bin/php -f sleep.php > /dev/null 2>&1 &");

Ответ 3

Вы также можете немедленно вернуть свой результат клиенту и продолжить обработку своего 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

Ответ 4

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

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

Это работает только после того, как вы меняете разрешения на cmd.exe - добавьте Read и Execute для IUSR_YOURMACHINE (я также установил write to Deny).

Ответ 5

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

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

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

Ответ 6

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

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

Ответ 7

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

Ответ 8

Для 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

Ответ 9

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