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

0

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

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

  • ОС: raspbian Os
  • Веб-сервер: NginX 1.2.1
  • Php: 5.4.3.6

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

  • ОС: Ubuntu
  • Веб-сервер: NginX 1.6.2
  • Php: 5.5.9

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

Вызов 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 и распознанием возвращаемого значения? Как это может быть потеряно? Кто-то догадывается?

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

Теги:
session
exec
freeze
radicale

2 ответа

-1
Лучший ответ

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

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

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

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

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

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

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

в

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

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

  • 0
    WTF? Твой оригинальный сценарий был «Служба радикального старта»? почему бы вам просто не запустить сервис и оставить его работающим ?? Для этого и нужны серверы. Кроме того, это не ошибка в PHP - это ошибка в том, как вы пишете свой код. у вас нет дела, нарушающего передовой опыт, чтобы назвать такой бессмысленный сценарий.
  • 0
    Ну, на самом деле факт заключается в том, что пользователь может отключить услугу, если ему это не нужно, без вызова ИТ. Иначе, делает ли это эту ошибку менее важной и менее проблемной? У вас странный взгляд на ИТ.
1

Вполне вероятно, что новая машина просто не настроена так, как устанавливалась малина PI -

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

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

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

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

<?php echo get_current_user();?> <?php echo get_current_user();?> - или альтернативно: <?php echo exec('whoami');?> <?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-пользователь.

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

  • 0
    Просто чтобы все знали, предоставление php неограниченного доступа sudo - плохая идея.
  • 1
    О, да, спасибо, что напомнили мне - я хотел упомянуть, что @castis - это лучше?
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню