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

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


person Abandoned account    schedule 01.11.2013    source источник
comment
Сначала посетите этот выпуск stackoverflow.com/questions/21659637/ Если не исправлено, возникают такие проблемы, как In Case, если вы застряли с импортом, tty или no askpass не работает, пожалуйста, проверьте эту ссылку, чтобы узнать, как его выполнить. stackoverflow.com/a/57978771/9470457 Спасибо !!!   -  person 3rdi    schedule 17.09.2019


Ответы (10)


Протестировано на 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, / usr / bin / env гарантирует, что используемый интерпретатор будет первым в $ PATH вашей среды. Альтернативой было бы жесткое кодирование чего-то вроде #! / Usr / bin / python; это нормально, но менее гибко.

В Unix исполняемый файл, предназначенный для интерпретации, может указывать, какой интерпретатор использовать, с помощью символа #! в начале первой строки, за которой следует интерпретатор (и любые необходимые ему флаги).

Если вы говорите о других платформах, конечно, это правило не применяется (но эта строка shebang не причиняет вреда и поможет, если вы когда-нибудь скопируете этот сценарий на платформу с базой Unix, такую ​​как Linux, Mac и т. Д. ).

Это применимо, когда вы запускаете его в Unix, сделав его исполняемым (chmod + x myscript.py), а затем запустив его напрямую: ./myscript.py, а не просто python myscript.py

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

chmod +x myscript.py

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

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

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

person Alejandro Quiroz    schedule 01.11.2013
comment
Спасибо, это помогло! Была еще одна проблема - пользователь Apache не мог выполнить команду в скрипте Python, но я смог исправить это, используя sudo и добавив исключение для моего скрипта в файл sudoers. Еще раз спасибо! :) - person Abandoned account; 03.11.2013
comment
Для OSX: echo shell_exec("/usr/local/bin/python3 /Users/cyborg/Dev/magic.py"); или: echo shell_exec("/usr/bin/python /Users/cyborg/Dev/magic.py"); - person Cyborg; 10.04.2020
comment
немного другое, но помогло мне диагностировать в debian: echo(exec("/usr/bin/python3 magic.py)); - person Colin Miles; 09.08.2020

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

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

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

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

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

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

person kqw    schedule 18.09.2015

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

файл sudoers: sudo visudo

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

person Colin Miles    schedule 27.07.2014
comment
Кажется неэффективным добавлять www-данные в sudoers и дает apache больше разрешений, которые ему нужны. Достаточно предоставить разрешения www-data для выполняемого скрипта. - person JasonRDalton; 31.07.2014
comment
Классная идея, но определенно может сделать вашу систему уязвимой. Я согласен с @JasonRDalton - person Reed; 27.02.2020

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

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

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

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

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

person Agnel Vishal    schedule 07.10.2018

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

person Tim Hallman    schedule 02.03.2018

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

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

  • 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");
person SMshrimant    schedule 20.06.2018

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

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

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

$command = escapeshellcmd('python blabla.py');
person Gerald Joshua    schedule 29.05.2018

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

<?php 

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

?>

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

person Punnerud    schedule 16.08.2020
comment
Это сработало для меня на виртуальном хостинге. - person Vishal Kumar Sahu; 29.11.2020

Все указанные выше параметры создают новый системный процесс. Это кошмар производительности. Для этого я сшил модуль PHP с прозрачными вызовами Python.

https://github.com/kirmorozov/runpy

Его может быть сложно скомпилировать, но он сохранит системные процессы и позволит вам сохранить время выполнения Python между вызовами PHP.

person Kirill Morozov    schedule 30.11.2020