Как я могу отлаживать проблемы exec ()?
Команда exec не работает на моем сервере, она ничего не делает, я отключил safe_mode и проверил, что все консольные команды работают, я пробовал с абсолютными путями. Я проверил разрешения для приложений и всех приложений, в которых мне нужны разрешения на выполнение. Я не знаю, что еще делать, вот краткое изложение кодов, которые я пробовал.
echo exec('/usr/bin/whoami'); echo exec('whoami'); exec('whoami 2>&1',$output,$return_val); if($return_val !== 0) { echo 'Error<br>'; print_r($output); } exec('/usr/bin/whoami 2>&1',$output,$return_val); if($return_val !== 0) { echo 'Error<br>'; print_r($output); }
Отображаются последние два кода:
Error Array ( )
Я связался с сервером, и они не могут мне помочь, они не знают, почему команда exec не работает. Простите мой плохой английский.
4 Solutions collect form web for “Как я могу отлаживать проблемы exec ()?”
посмотрите /etc/php.ini , там:
; This directive allows you to disable certain functions for security reasons. ; It receives a comma-delimited list of function names. This directive is ; *NOT* affected by whether Safe Mode is turned On or Off. ; http://www.php.net/manual/en/ini.sect.safe-mode.php#ini.disable-functions disable_functions =
убедитесь, что exec не указан в следующем виде:
disable_functions=exec
Если это так, удалите его и перезапустите apache.
Для легкой отладки я обычно обычно запускаю файл php вручную (может запрашивать больше ошибок, не устанавливая его в основном ini). для этого добавьте заголовок:
#!/usr/bin/php ini_set("display_errors", 1); ini_set("track_errors", 1); ini_set("html_errors", 1); error_reporting(E_ALL);
в начало файла, дайте ему разрешения с помощью chmod +x myscript.php и выполните его ./myscript.php . Он очень внимателен, особенно на занятом сервере, который много записывает в файл журнала.
РЕДАКТИРОВАТЬ
Звучит как проблема с разрешениями . Создайте сценарий bash, который делает что-то простое, как echo "helo world" и попытайтесь запустить его. Убедитесь, что у вас есть разрешения для файла и папки, содержащей файл . вы можете просто сделать chmod 755 только для тестирования.
Вы можете возвращать выходные данные и возвращать код команд exec , тоски могут содержать информацию, которая могла бы объяснить проблему …
exec('my command', $output, $return);
Поскольку вы выходите из контекста PHP в родную оболочку, у вас будет много отладочных задач.
Самый лучший и самый надежный, который я использовал в прошлом, – это запись вывода сценария в файл журнала и его удаление во время выполнения PHP.
<?php shell_exec("filename > ~/debug.log 2>&1");
Затем в отдельной оболочке:
tail -200f ~/debug.log
Когда вы выполняете свой PHP-скрипт, ваши ошибки и вывод из вашего вызова оболочки будут отображаться в вашем файле debug.log .
Еще несколько заметок.
-
Для отладки всегда завершайте функцию exec / shell_exec в
var_dump(). -
error_reporting(-1);должен бытьset_error_handler("var_dump");, как и должно бытьdisplay_errors, в качестве последнего средства дажеset_error_handler("var_dump");– если бы только, чтобы убедиться, что сам PHP не вызывалexecvpили еще. -
Используйте
2>&1(объедините оболочки STDERR в поток STDOUT), чтобы узнать, почему вызов вызывается.
В некоторых случаях вам может потребоваться обернуть команду в дополнительный вызов оболочки:// capture STDERR stream via standard shell shell_exec("/bin/sh -c 'ffmpeg -opts 2>&1' ");Повторите перенаправление журнала, как рекомендовано @Mike – наиболее рекомендуемый подход.
-
Заменяйте между различными функциями exec, чтобы в противном случае вскрыть сообщения об ошибках. Хотя они в основном делают то же самое, выходные пути возврата меняются:
-
exec()→ либо возвращает результат как результат функции, либо через необязательный параметр$outputparamater.
Также предоставляет параметр$return_var, который содержит код errno / exit приложения запуска или оболочки. Вы можете получить:-
ENOENT(2) – Нет такого файла -
EIO(127) – Ошибка ввода-вывода: файл не найден
-
-
shell_exec()→ то, что вы хотите запускать в основном для выражений в стиле оболочки.
Обязательно назначьте / напечатайте возвращаемое значение, например,var_dump(shell_exec("...")); -
``inline backticks → идентичныshell_exec. -
system()→ похожа наexec, но всегда возвращает результат как результат функции (распечатайте!). Дополнительно позволяет фиксировать код результата. -
passthru()→ еще одна альтернативаexec, но всегда отправляет любые результаты STDOUT в выходной буфер PHP. Какой из них делает его наиболее подходящей оболочкой exec. -
popen()или лучшеproc_open()→ позволяют индивидуально фиксировать STDOUT и STDERR.
-
-
Большинство ошибок оболочки заканчиваются на PHP или Apache
error.logкогда они не перенаправлены. Проверьте свой журнал syslog или Apache, если ничего не дает полезных сообщений об ошибках.
Наиболее распространенными проблемами, возникающими у новичков PHP / LAMP, являются:
-
Как уже упоминалось @Kuf: для устаревших планов веб-хостинга вы все равно можете найти
safe_modeилиdisable_functions. Ни одна из функций exec PHP не будет работать. (Лучше всего найти лучшего провайдера, иначе расследовать «CGI» – но не устанавливайте собственный интерпретатор PHP, пока не разбираетесь.) -
Аналогично, AppArmor / SELinux / Firejail иногда могут быть на месте. Они ограничивают способность каждого приложения создавать новые процессы.
-
Предложенный двоичный код не существует . Практически ни один веб-хост не имеет таких инструментов, как
ffmpegpreinstalled. Вы не можете просто запускать произвольные команды оболочки без подготовки. Некоторые вещи необходимо установить!// Check if `ffmpeg` is actually there: var_dump(shell_exec("which ffmpeg")); -
PATHвыключен. Если вы установили специальные инструменты, вам необходимо убедиться, что они доступны. Использованиеvar_dump(shell_exec("ffmpeg -opts"))будет искать все распространенные пути – или как было сказано / ограничено Apache (часто просто/bin:/usr/bin).Проверьте с помощью
print_r($_SERVER);что содержится в вашей PATH, и если это покрывает инструмент, который вы хотите запустить. Кроме того, вам может потребоваться адаптировать настройки сервера (/ etc / apache2 / envvars) или использовать полные пути:// run with absolute paths to binary var_dump(shell_exec("/bin/sh -c '/usr/local/bin/ffmpeg -opts 2>&1'"));Это несколько подрывает концепцию оболочки. Лично я не считаю это предпочтительным. Однако это имеет смысл для целей безопасности; конечно, для использования пользовательской установки.
-
права доступа
-
Чтобы запустить двоичный код в системе BSD / Linux, его нужно сделать «исполняемым». Это то, что делает
chmod a+x ffmpeg. -
Дальнейшее изменение пути к таким пользовательским двоичным файлам должно быть доступно для чтения пользователю Apache , с которым работают ваши скрипты PHP.
-
Более современные настройки используют PHP, встроенные в режим FPM (suexec + FastCGI), где ваша учетная запись веб-хостинга равна тому, с чего работает PHP.
-
-
Тест с SSH . Это должно быть само собой разумеющимся, но перед запуском команд через PHP тестирование его в реальной оболочке было бы очень разумным. Зонд, например,
ldd ffmpegесли все зависимости lib находятся там, и если он работает иначе. -
Входные значения (GET, POST, имена FILE, пользовательские данные), которые передаются как аргументы команды в строках exec, должны быть экранированы с помощью
escapeshellarg().$q = "escapeshellarg"; var_dump(shell_exec("echo {$q($_GET['text'])} | wc"));В противном случае вы легко получите синтаксические ошибки оболочки; и, вероятно, использовать код, установленный позже …