сессия — php зависает при выполнении внешнего скрипта sh

Я попытаюсь объяснить мою проблему в истории временной шкалы:

Я попытался запустить несколько внешних скриптов из php и снова вернуть код выхода на сервер с помощью вызова ajax.
Один вызов должен запустить или остановить службу на этом компьютере. Это прекрасно работает на этой развивающейся машине.

  • ОС: Распбиан Ос
  • Веб-сервер: NginX 1.2.1
  • Php: 5.4.3.6

Однако я экспортировал код на большую машину с гораздо большей мощностью, и все, казалось, работало нормально, но одно:
Один вызов заставляет php-fpm зависать и никогда не возвращаться. При детальном рассмотрении я выяснил, что вызов зомби создал процесс, который я не могу прекратить (даже с помощью sudo).

  • ОС: Ubuntu
  • Веб-сервер: NginX 1.6.2
  • Php: 5.5,9

Казалось, что единственным решением было остановить процесс php-fpm, а затем перезапустить его. Кажется, что все снова работает нормально, пока я снова пытаюсь вызвать этот скрипт.

Вызов php линии

exec("sudo ".$script, $output, $return_var);

(Со всеми переменными являются обычные «строки» без специальных символов)

Запустить скрипт

#!/bin/sh
service radicale start 2>&1

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

Поиск в Google привел меня к тому, что между командами php возник конфликт Exec () а также session_start ().

Ссылки:

https://bugs.php.net/bug.php?id=44942

https://bugs.php.net/bug.php?id=44994

Они пришли к выводу, что эту ошибку можно обойти с помощью такой конструкции:

...
session_write_close();
exec("sudo ".$script, $output, $return_var);
session_start();
...

Но это, на мой взгляд, было не отладкой, а скорее беспомощным обходным путем, потому что вы теряете функциональность, позволяя пользователю знать, что его действия полностью функционировали, но больше позволяете ему поверить, что произошла ошибка. Гораздо более запутанным является тот факт, что он полностью работает на Raspberry Pi A, но не на 64-битной машине с гораздо большим процессором и 8 ГБ оперативной памяти.

Так есть ли реальное решение где-нибудь или это обходной путь единственный способ решить эту проблему? Я читал статью о том, что у php есть некоторые пробники с exec / shell_exec и распознавание возвращаемого значения? Как это может быть потеряно? У кого-то есть предположение?

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

0

Решение

Вполне вероятно, что новая машина просто не настроена так, как Raspberry PI —

Вам нужно сделать несколько вещей в вашей оболочке, прежде чем это сработает на вашей большой машине:

1). Разрешить php использовать sudo.

sudo usermod -G sudo -a your-php-user

Обратите внимание, что для получения имени пользователя your-php-user, вы можете просто запустить скрипт, который говорит:

<?php echo get_current_user(); ?> — или альтернативно:
<?php echo exec('whoami'); ?>

2). Разрешить этому пользователю использовать sudo без пароля

sudo visudo — эта команда откроется /etc/sudoers с отказоустойчивым, чтобы удержать вас от чего-либо.

Добавьте эту строку в самый конец:

your-php-user ALL=(ALL) NOPASSWD: /path/to/your/script,/path/to/other/script

Вы можете поместить столько скриптов, разделенных запятыми, сколько вам нужно.
Теперь ваш скрипт должен работать просто отлично.

ОПЯТЬ, обратите внимание, что вам нужно изменить your-php-user кем бы ни был ваш php-пользователь.

Надеюсь это поможет!

1

Другие решения

Это не настоящее решение, но это лучшее решение, чем нет.

Вызов сценария bash с

<?php
...
exec("sudo ".$script, $output, $return_var);
...
?>

заканчивается только в этом особом случае в теме зомби. Поскольку php-fpm ожидает результатов в ожидании, он все еще удерживает линию, не сдаваясь и не прерывая время для остальной части своего потока, все еще живого. Таким образом, каждый второй запрос к серверу php все еще находится в очереди и никогда не будет обработан. Это может быть хорошо для некоторых долгоживущих или рабочих потоков, но мой запрос был выполнен за несколько [мс].

Я не нашел причину для этого. Насколько я мог делать отладку, я не был вызван ошибкой процесса Radicale, потому что это давало в любое время чистый и смелый 0, как взамен. Казалось, что процесс php просто не может получить от него обратную строку, и поэтому он все еще ждет и ждет.

Нет времени, я изменил сценарий сбоя

#!/bin/sh
service radicale start 2>&1

в

#!/bin/sh
service radicale start > /dev/null 2>&1 &

… так что сигнализируя каждую возвращающуюся линию в нирвану и отключая все подпрограммы. На данный момент сервер не зависал и работает по желанию. Но ощущение, что это может быть серьезной ошибкой в ​​php, все еще остается в моей голове, с надеждой, что когда-нибудь кто-нибудь может победить эту ошибку.

-1

По вопросам рекламы [email protected]