Запуск скрипта Python из PHP

114

Я пытаюсь запустить сценарий Python из 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 имеет разрешения на доступ к файлу и его выполнение.

РЕДАКТИРОВАТЬ: Благодаря Алехандро я смог решить проблему. Если у вас такая же проблема, не забывайте, что ваш веб-сервер, вероятно / надеюсь, не работает от имени пользователя root. Попробуйте войти в систему как пользователь вашего веб-сервера или пользователь с аналогичными разрешениями и попробуйте выполнить команды самостоятельно.

Заброшенный аккаунт
источник
Сначала посетите эту проблему stackoverflow.com/questions/21659637/. Если не исправлено, и у вас возникнут проблемы, например, В случае, если вы застряли с импортом или tty или не работает ни один запрос, проверьте эту ссылку, чтобы получить подробные инструкции по его выполнению. stackoverflow.com/a/57978771/9470457 Спасибо !!!
3rdi,

Ответы:

159

Протестировано на 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проверьте этот текст в первой строке: (см. Объяснение Shebang) :

#!/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
Алехандро Кирос
источник
6
Спасибо, это помогло! Была еще одна проблема - пользователь Apache не мог выполнить команду в скрипте Python, но я смог исправить это, используя sudo и добавив исключение для моего скрипта в файл sudoers. Еще раз спасибо! :)
Заброшенный аккаунт
1
Я столкнулся с той же проблемой, что и пользователь apache, не могли бы вы помочь мне?
Эмма
1
Я использовал ваш ответ, он отлично выполняет скрипт python, но я не могу повторить результаты, на веб-странице ничего не отображается, вы можете мне помочь.
Хамди Чареф
1
"#! / usr / bin / env python" в первой строке помогло мне. Большой!
C3PO
1
Для OSX: echo shell_exec("/usr/local/bin/python3 /Users/cyborg/Dev/magic.py"); или:echo shell_exec("/usr/bin/python /Users/cyborg/Dev/magic.py");
Cyborg
24

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

ob_start();
passthru('/usr/bin/python2.7 /srv/http/assets/py/switch.py arg1 arg2');
$output = ob_get_clean(); 
Никлас Линдблад
источник
16

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

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

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

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

kqw
источник
8

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

файл sudoers: sudo visudo

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

Колин Майлз
источник
7
Кажется неэффективным добавлять www-данные в sudoers и дает apache больше разрешений, которые ему нужны. Достаточно предоставить разрешения www-data для выполняемого скрипта.
JasonRDalton
Классная идея, но определенно может сделать вашу систему уязвимой. Я согласен с @JasonRDalton
Reed
6

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

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

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

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

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

Агнель Вишал
источник
4

В моем случае мне нужно было создать новую папку в 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!

Тим Холлман
источник
3

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

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

  • 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";
	}
?>

mkdir.py

#!/usr/bin/env python    
import os    
os.makedirs("thisfolder");
SMshrimant
источник
1

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

sh: blabla.py: команда не найдена

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

$command = escapeshellcmd('python blabla.py');
Джеральд Джошуа
источник
0

В духе Алехандро Кироза:

<?php 

$command = escapeshellcmd('python test.py');
$output = shell_exec($command);
echo $output;

?>

Необходимо добавить Python, а путь не нужен.

Пуннеруд
источник