Как я могу отлаживать проблемы 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); } 

Отображаются последние два кода:

  • PHP - получить все ключи из массива, которые начинаются с определенной строки
  • Передайте строку PHP переменной JavaScript (и удалите строки перевода)
  • PHP-перенаправление с переменными строки запроса HTTP
  • PHP mysql ищет несколько таблиц с помощью ключевого слова
  • Как я могу извлечь изображения из PDF-файла?
  • Symfony 2 Создайте поле формы объекта с двумя свойствами
  •  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, чтобы в противном случае вскрыть сообщения об ошибках. Хотя они в основном делают то же самое, выходные пути возврата меняются:

      1. exec() → либо возвращает результат как результат функции, либо через необязательный параметр $output paramater.
        Также предоставляет параметр $return_var , который содержит код errno / exit приложения запуска или оболочки. Вы можете получить:

        • ENOENT (2) – Нет такого файла
        • EIO (127) – Ошибка ввода-вывода: файл не найден
      2. shell_exec() → то, что вы хотите запускать в основном для выражений в стиле оболочки.
        Обязательно назначьте / напечатайте возвращаемое значение, например, var_dump(shell_exec("..."));

      3. `` inline backticks → идентичны shell_exec .

      4. system() → похожа на exec , но всегда возвращает результат как результат функции (распечатайте!). Дополнительно позволяет фиксировать код результата.

      5. passthru() → еще одна альтернатива exec , но всегда отправляет любые результаты STDOUT в выходной буфер PHP. Какой из них делает его наиболее подходящей оболочкой exec.

      6. 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 иногда могут быть на месте. Они ограничивают способность каждого приложения создавать новые процессы.

    • Предложенный двоичный код не существует . Практически ни один веб-хост не имеет таких инструментов, как ffmpeg preinstalled. Вы не можете просто запускать произвольные команды оболочки без подготовки. Некоторые вещи необходимо установить!

       // 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'")); 

      Это несколько подрывает концепцию оболочки. Лично я не считаю это предпочтительным. Однако это имеет смысл для целей безопасности; конечно, для использования пользовательской установки.

    • права доступа

      1. Чтобы запустить двоичный код в системе BSD / Linux, его нужно сделать «исполняемым». Это то, что делает chmod a+x ffmpeg .

      2. Дальнейшее изменение пути к таким пользовательским двоичным файлам должно быть доступно для чтения пользователю Apache , с которым работают ваши скрипты PHP.

      3. Более современные настройки используют 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")); 

      В противном случае вы легко получите синтаксические ошибки оболочки; и, вероятно, использовать код, установленный позже …

    PHP is the Best Programming Language in the world.