У меня есть сценарий PHP, который должен вызывать сценарий оболочки, но не заботится о выводе. Сценарий оболочки выполняет несколько вызовов SOAP и выполняется медленно, поэтому я не хочу замедлять запрос PHP, пока он ожидает ответа. Фактически, PHP-запрос должен иметь возможность завершиться без завершения процесса оболочки.
Я посмотрел в различные exec()
, shell_exec()
, pcntl_fork()
функции и т.д., но ни один из них не кажется, предлагают именно то , что я хочу. (Или, если они это сделают, мне не понятно, как.) Есть предложения?
php
asynchronous
shell
AdamTheHutt
источник
источник
nice
иionice
предотвратить его перегрузку вашей системы (например/usr/bin/ionice -c3 /usr/bin/nice -n19
)Ответы:
Если он "не заботится о выводе", не может ли быть вызван exec для сценария с помощью
&
background для процесса?РЕДАКТИРОВАТЬ - включив то, что @ AdamTheHut прокомментировал к этому сообщению, вы можете добавить это к звонку
exec
:Это перенаправит и
stdio
(first>
), иstderr
(2>
)/dev/null
в фоновый режим.Есть другие способы сделать то же самое, но это самый простой для чтения.
Альтернатива вышеупомянутому двойному перенаправлению:
источник
&> /dev/null &
: xdebug не будет генерировать логи, если вы используете это. Проверьте stackoverflow.com/questions/4883171/…/dev/null
является лучшей практикой, поскольку запись в закрытые FD вызывает ошибки, тогда как попытки чтения или записи/dev/null
просто молча ничего не делают.Я использовал в для этого, поскольку это действительно начинает независимый процесс.
источник
www-data
), не имеет разрешений на использование,at
и вы не можете его настроить, вы можете попробовать использовать<?php exec('sudo sh -c "echo \"command\" | at now" ');
If,command
содержащий кавычки, см. escapeshellarg, чтобы избавить вас от головной болиecho "sudo command" | at now
и комментированиюwww-data
в/etc/at.deny
Для всех пользователей Windows: я нашел хороший способ запустить асинхронный PHP-скрипт (на самом деле он работает практически со всем).
Он основан на командах popen () и pclose (). И хорошо работает как на Windows, так и на Unix.
Оригинальный код от: http://php.net/manual/en/function.exec.php#86329
источник
myscript.js
а вместо этого, вы будете писатьnode myscript.js
. То есть: узел - это исполняемый файл, myscript.js - это, ну, в общем , скрипт для выполнения. Существует огромная разница между исполняемым файлом и скриптом.php artisan
просто оставьте здесь комментарий, чтобы не было необходимости отслеживать, почему он не будет работать с командамиНа Linux вы можете сделать следующее:
Это выполнит команду в командной строке, а затем просто вернет PID, который можно проверить на> 0, чтобы убедиться, что он работает.
Этот вопрос похож: есть ли у PHP многопоточность?
источник
action=generate var1_id=23 var2_id=35 gen_id=535
сегмент). Кроме того, поскольку OP спросил о запуске сценария оболочки, вам не нужны специфичные для PHP части. Окончательный код будет:$cmd = 'nohup nice -n 10 /path/to/script.sh > /path/to/log/file.log & printf "%u" $!';
nice
но иionice
.&
запускает предыдущий код в фоновом режиме, затемprintf
используется для форматированного вывода$!
переменной, содержащей PIDУ php-execute-a-background-process есть несколько хороших предложений. Я думаю, что мой довольно хорошо, но я предвзятый :)
источник
В Linux вы можете запустить процесс в новом независимом потоке, добавив амперсанд в конце команды
В Windows вы можете использовать команду «start» DOS
источник
start
команда на windows, она не запускается асинхронно ... Не могли бы вы указать источник, откуда вы получили эту информацию?/B
параметра. Я объяснил это здесь: stackoverflow.com/a/34612967/1709903правильный способ (!) сделать это
fork-вилки, setsid сообщают текущему процессу, чтобы он стал главным (без родителя), execve говорят, что вызывающий процесс должен быть заменен вызываемым. так что родитель может выйти, не влияя на ребенка.
источник
Я использовал это ...
(где
PHP_PATH
const определяется какdefine('PHP_PATH', '/opt/bin/php5')
или подобное)Он передает аргументы через командную строку. Чтобы прочитать их в PHP, смотрите argv .
источник
Единственный способ, который я нашел, который действительно работал для меня, был:
источник
shell_exec("/usr/local/sbin/command.sh 2>&1 >/dev/null | at now & disown")
и все, что я получаю, это:sh: 1: disown: not found
Я также нашел Symfony Process Component полезным для этого.
Посмотрите, как это работает в репозитории GitHub .
источник
proc_*
внутренних функциях.Вы также можете запустить скрипт PHP как демон или cronjob :
#!/usr/bin/php -q
источник
Используйте названный fifo.
Затем, когда вы захотите запустить долгосрочную задачу, просто напишите новую строку (неблокирующую в файле триггера).
Пока ваш ввод меньше, чем
PIPE_BUF
однаwrite()
операция, вы можете записывать аргументы в fifo и отображать их как$REPLY
в скрипте.источник
без использования очереди вы можете использовать
proc_open()
как это:источник