Uruchamianie skryptu w Pythonie z PHP

114

Próbuję uruchomić skrypt w Pythonie z PHP za pomocą następującego polecenia:

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

Jednak PHP po prostu nie generuje żadnych danych wyjściowych. Raportowanie błędów jest ustawione na E_ALL, a display_errors jest włączone.

Oto, czego próbowałem:

  • Kiedyś python2, /usr/bin/python2a python2.7zamiast/usr/bin/python2.7
  • Użyłem również ścieżki względnej zamiast ścieżki bezwzględnej, która również niczego nie zmienia.
  • Próbowałem za pomocą komendy exec, shell_exec, system.

Jeśli jednak biegnę

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

działa doskonale, ale shutdown nownic nie robi.

PHP ma uprawnienia dostępu i wykonywania pliku.

EDYCJA: Dzięki Alejandro udało mi się naprawić problem. Jeśli masz ten sam problem, nie zapominaj, że twój serwer WWW prawdopodobnie / miejmy nadzieję nie działa jako root. Spróbuj zalogować się jako użytkownik serwera WWW lub użytkownik z podobnymi uprawnieniami i spróbuj samodzielnie uruchomić polecenia.

Opuszczone konto
źródło
Najpierw odwiedź ten problem stackoverflow.com/questions/21659637/… Jeśli problem nie zostanie rozwiązany, a pojawią się problemy, takie jak In Case, jeśli utkniesz z importem lub tty lub nie działa askpass, sprawdź ten link, aby uzyskać szczegółowe instrukcje, jak go wykonać. stackoverflow.com/a/57978771/9470457 Dzięki !!!
3

Odpowiedzi:

159

Testowane na Ubuntu Server 10.04. Mam nadzieję, że pomoże ci to również w Arch Linux.

W PHP użyj funkcji shell_exec :

Wykonaj polecenie przez powłokę i zwróć kompletne dane wyjściowe jako ciąg.

Zwraca dane wyjściowe z wykonanego polecenia lub NULL, jeśli wystąpił błąd lub polecenie nie generuje wyniku.

<?php 

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

?>

W pliku Pythona test.pysprawdź ten tekst w pierwszej linii: (zobacz wyjaśnienie shebang) :

#!/usr/bin/env python

Również plik Pythona musi mieć odpowiednie uprawnienia (wykonanie dla użytkownika www-data / apache, jeśli skrypt PHP działa w przeglądarce lub curl) i / lub musi być „wykonywalny”. Również wszystkie komendy do .pypliku muszą mieć odpowiednie uprawnienia:

Zaczerpnięte z podręcznika PHP :

Tylko szybkie przypomnienie dla tych, którzy próbują używać shell_exec na platformie typu unix i nie mogą go uruchomić. PHP jest uruchamiane jako użytkownik sieciowy w systemie (zwykle www dla Apache), więc musisz się upewnić, że użytkownik sieciowy ma prawa do wszystkich plików lub katalogów, których próbujesz użyć w poleceniu shell_exec. Poza tym wydaje się, że nic nie robi.

Aby uczynić plik wykonywalny na platformach typu unix :

chmod +x myscript.py
Alejandro Quiroz
źródło
6
Dziękuję, to załatwiło sprawę! Był jeszcze jeden problem - użytkownik Apache nie był w stanie wykonać polecenia w skrypcie Pythona, ale udało mi się to naprawić, używając sudo i dodając wyjątek dla mojego skryptu do pliku sudoers. Dzięki jeszcze raz! :)
Opuszczone konto
1
Mam ten sam problem z użytkownikiem apache, czy możesz mnie poprowadzić?
Emma
1
Użyłem Twojej odpowiedzi, skrypt Pythona został wykonany dobrze, ale nie mogę powtórzyć wyników, które nie pojawiają się na stronie internetowej, czy możesz mi pomóc.
Hamdi Charef
1
„#! / usr / bin / env python” w pierwszym wierszu załatwiło sprawę. Wspaniały!
C3PO
1
Dla OSX: echo shell_exec("/usr/local/bin/python3 /Users/cyborg/Dev/magic.py"); lub:echo shell_exec("/usr/bin/python /Users/cyborg/Dev/magic.py");
Cyborg
24

Zalecam bezpośrednie używanie passthrui obsługę bufora wyjściowego:

ob_start();
passthru('/usr/bin/python2.7 /srv/http/assets/py/switch.py arg1 arg2');
$output = ob_get_clean(); 
Niklas Lindblad
źródło
16

Jeśli chcesz poznać stan powrotu polecenia i uzyskać wszystkie stdoutdane wyjściowe, możesz użyć exec:

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

$outjest tablicą wszystkich linii. $statusto status zwrotu. Bardzo przydatne do debugowania.

Jeśli chcesz również zobaczyć stderrwyjście, możesz albo pobawić się proc_open, albo po prostu dodać 2>&1do swojego $command. To ostatnie często wystarcza, aby wszystko działało i znacznie szybciej je „wdrożyło”.

kqw
źródło
8

Alejandro załatwił to, dodając wyjaśnienie do wyjątku (Ubuntu lub Debian) - nie mam przedstawiciela, który mógłby dodać do samej odpowiedzi:

plik sudoers: sudo visudo

dodano wyjątek: www-data ALL=(ALL) NOPASSWD: ALL

Colin Miles
źródło
7
Nie wydaje się skuteczne dodawanie danych www do sudoers i daje apache więcej uprawnień, których potrzebuje. Nadanie uprawnień danych www do wykonywanego skryptu wystarczyłoby.
JasonRDalton
Fajny pomysł, ale z pewnością może narazić system na niebezpieczeństwo. Zgadzam się z @JasonRDalton
Reed
6

Aby wyjaśnić, którego polecenia użyć w zależności od sytuacji

exec() - Uruchom program zewnętrzny

system() - Uruchom program zewnętrzny i wyświetl dane wyjściowe

passthru() - Uruchom program zewnętrzny i wyświetl nieprzetworzone dane wyjściowe

Źródło: http://php.net/manual/en/function.exec.php

Agnel Vishal
źródło
4

W moim przypadku musiałem utworzyć nowy folder w wwwkatalogu o nazwie scripts. W ramach scriptsdodałem nowy plik o nazwietest.py .

Następnie użyłem sudo chown www-data:root scriptsi sudo chown www-data:root test.py.

Potem poszedłem do nowego scriptskatalogu i użyłem sudo chmod +x test.py.

Mój plik test.py wygląda tak. Zwróć uwagę na inną wersję Pythona:

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

Z php teraz robię to:

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

Powinieneś zobaczyć: Hello World!

Tim Hallman
źródło
3

Powyższe metody wydają się skomplikowane. Użyj mojej metody jako odniesienia.

Mam te dwa pliki:

  • run.php

  • mkdir.py

Tutaj utworzyłem stronę HTML, która zawiera GOprzycisk. Za każdym razem, gdy naciśniesz ten przycisk, nowy folder zostanie utworzony w katalogu, do którego podałeś ścieżkę.

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
źródło
1

To takie trywialne, ale chciałem tylko pomóc każdemu, kto już zastosował się do sugestii Alejandro, ale napotkał ten błąd:

sh: blabla.py: nie znaleziono polecenia

Jeśli ktoś napotkał ten błąd, musi wprowadzić małą zmianę w pliku php autorstwa Alejandro:

$command = escapeshellcmd('python blabla.py');
Gerald Joshua
źródło
0

Zainspirowany Alejandro Quirozem:

<?php 

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

?>

Musisz dodać Python i nie potrzebujesz ścieżki.

Punnerud
źródło