Запуск Python script из PHP

Я пытаюсь запустить Python script из PHP, используя следующую команду:

exec('/usr/bin/python2.7 /srv/http/assets/py/switch.py arg1 arg2');

Однако PHP просто не производит никакого вывода. Отчет об ошибках установлен в E_ALL, а display_errors включен.

Вот что я пробовал:

  • Я использовал python2, /usr/bin/python2 и python2.7 вместо /usr/bin/python2.7
  • Я также использовал относительный путь вместо абсолютного пути, который тоже ничего не менял.
  • Я пробовал использовать команды exec, shell_exec, system.

Однако, если я запустил

if (exec('echo TEST') == 'TEST')
{
    echo 'exec works!';
}

он отлично работает, а shutdown now ничего не делает.

У PHP есть разрешения на доступ и выполнение файла.

EDIT: Благодаря Алехандро, я смог решить проблему. Если у вас есть такая же проблема, не забывайте, что ваш веб-сервер, вероятно, не работает с правами root. Попробуйте войти в систему как пользователь вашего веб-сервера или пользователь с аналогичными разрешениями и попробуйте сами выполнить команды.

Ответ 1

Протестировано на Ubuntu Server 10.04. Надеюсь, это поможет вам и в Arch Linux.

В PHP используйте функцию shell_exec:

Выполните команду через оболочку и верните весь вывод в виде строки.

Возвращает вывод выполненной команды или NULL в случае ошибки произошла, или команда не производит вывод.

<?php 

$command = escapeshellcmd('/usr/custom/test.py');
$output = shell_exec($command);
echo $output;

?>

В файле Python test.py проверьте этот текст в первой строке: (см. объяснение Шебанга):

#!/usr/bin/env python

Также файл Python должен иметь правильные привилегии (выполнение для пользователя www-data/apache, если скрипт PHP запускается в браузере или в curl) и/или должен быть "исполняемым". Также все команды в файле .py должны иметь правильные права доступа:

Взято из руководства php:

Просто быстрое напоминание для тех, кто пытается использовать shell_exec на Unix-типа платформы и не может заставить его работать. PHP выполняется как веб-пользователь в системе (как правило, www для Apache), поэтому вам нужно убедитесь, что веб-пользователь имеет права на любые файлы или каталоги, которые вы пытаетесь использовать в команде shell_exec. С другой стороны, похоже, что он ничего не делает.

Чтобы сделать исполняемый файл на платформах Unix-типа:

chmod +x myscript.py

Ответ 2

Я рекомендую использовать passthru и напрямую обращаться с выходным буфером:

ob_start();
passthru('/usr/bin/python2.7 /srv/http/assets/py/switch.py arg1 arg2');
$output = ob_get_clean(); 

Ответ 3

Если вы хотите узнать статус возврата команды и получить весь вывод stdout, вы можете фактически использовать exec:

$command = 'ls';
exec($command, $out, $status);

$out - это массив всех строк. $status - это статус возврата. Очень полезно для отладки.

Если вы также хотите видеть вывод stderr, вы можете либо играть с proc_open, либо просто добавить 2>&1 в свой $command, Последнее часто бывает достаточно для того, чтобы заставить вещи работать и быстрее "внедрять".

Ответ 4

Алехандро прибил его, добавив разъяснение к исключению (Ubuntu или Debian) - у меня нет ответа, чтобы добавить к самому ответу:

файл sudoers: sudo visudo

добавлено исключение: www-data ALL=(ALL) NOPASSWD: ALL

Ответ 5

Чтобы уточнить, какую команду использовать в зависимости от ситуации

exec() - выполнить внешнюю программу

system() - выполнить внешнюю программу и отобразить вывод

passthru() - выполнить внешнюю программу и отобразить исходный вывод

Источник: http://php.net/manual/en/function.exec.php

Ответ 6

В моем случае мне нужно было создать новую папку в каталоге www называемой scripts. Внутри scripts я добавил новый файл test.py

Затем я использовал sudo chown www-data:root scripts и sudo chown www-data:root test.py

Затем я перешел в новый каталог scripts и использовал sudo chmod +x test.py

Мой файл test.py выглядит так. Обратите внимание на другую версию Python:

#!/usr/bin/env python3.5
print("Hello World!")

От php теперь я делаю это:

$message = exec("/var/www/scripts/test.py 2>&1");
print_r($message);

И вы должны увидеть: Hello World!

Ответ 7

Вышеуказанные методы кажутся сложными. Используйте мой метод в качестве ссылки.

У меня есть эти два файла:

  • run.php

  • mkdir.py

Здесь я создал HTML-страницу, которая содержит кнопку GO. Каждый раз, когда вы нажимаете эту кнопку, в каталоге, путь которого вы указали, будет создана новая папка.

run.php

<html>
 <body>
  <head>
   <title>
     run
   </title>
  </head>

   <form method="post">

    <input type="submit" value="GO" name="GO">
   </form>
 </body>
</html>

<?php
	if(isset($_POST['GO']))
	{
		shell_exec("python /var/www/html/lab/mkdir.py");
		echo"success";
	}
?>

Ответ 8

Это так тривиально, но я просто хотел помочь любому, кто уже последовал предложению Алехандро, но столкнулся с этой ошибкой:

sh: blabla.py: command not found

Если кто-то сталкивался с этой ошибкой, то Alejandro должен внести небольшие изменения в php файл:

$command = escapeshellcmd('python blabla.py');