Ausführen eines Python-Skripts über PHP

113

Ich versuche, ein Python-Skript über PHP mit dem folgenden Befehl auszuführen:

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

PHP erzeugt jedoch einfach keine Ausgabe. Die Fehlerberichterstattung ist auf E_ALL gesetzt und display_errors ist aktiviert.

Folgendes habe ich versucht:

  • Ich verwendet python2, /usr/bin/python2und python2.7statt/usr/bin/python2.7
  • Ich habe auch einen relativen Pfad anstelle eines absoluten Pfads verwendet, der auch nichts geändert hat.
  • Ich habe versucht , die Befehle exec, shell_exec, system.

Allerdings, wenn ich renne

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

es funktioniert einwandfrei, shutdown nowmacht aber nichts.

PHP hat die Berechtigung, auf die Datei zuzugreifen und sie auszuführen.

EDIT: Dank Alejandro konnte ich das Problem beheben. Wenn Sie das gleiche Problem haben, vergessen Sie nicht, dass Ihr Webserver wahrscheinlich / hoffentlich nicht als Root ausgeführt wird. Melden Sie sich als Benutzer Ihres Webservers oder als Benutzer mit ähnlichen Berechtigungen an und versuchen Sie, die Befehle selbst auszuführen.

Verlassenes Konto
quelle
Besuchen Sie zuerst dieses Problem stackoverflow.com/questions/21659637/… Wenn es nicht behoben ist und Sie Probleme wie Wenn Sie mit Importen oder tty stecken bleiben oder kein Askpass nicht funktioniert, überprüfen Sie bitte diesen Link für detaillierte Schritte, um es auszuführen. stackoverflow.com/a/57978771/9470457 Danke !!!
3.

Antworten:

157

Getestet auf Ubuntu Server 10.04. Ich hoffe es hilft dir auch unter Arch Linux.

Verwenden Sie in PHP die Funktion shell_exec :

Führen Sie den Befehl über die Shell aus und geben Sie die vollständige Ausgabe als Zeichenfolge zurück.

Es gibt die Ausgabe des ausgeführten Befehls oder NULL zurück, wenn ein Fehler aufgetreten ist oder der Befehl keine Ausgabe erzeugt.

<?php 

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

?>

test.pyÜberprüfen Sie in der Python-Datei diesen Text in der ersten Zeile: (siehe shebang EXPLAIN) :

#!/usr/bin/env python

Außerdem muss die Python-Datei über die richtigen Berechtigungen verfügen (Ausführung für den Benutzer www-data / apache, wenn das PHP-Skript im Browser oder Curl ausgeführt wird) und / oder "ausführbar" sein. Außerdem müssen alle Befehle in der .pyDatei die richtigen Berechtigungen haben:

Entnommen aus dem PHP-Handbuch :

Nur eine kurze Erinnerung für diejenigen, die versuchen, shell_exec auf einer Unix-Plattform zu verwenden und es scheinbar nicht zum Laufen bringen können. PHP wird als Webbenutzer auf dem System ausgeführt (im Allgemeinen www für Apache). Sie müssen daher sicherstellen, dass der Webbenutzer Rechte für alle Dateien oder Verzeichnisse hat, die Sie im Befehl shell_exec verwenden möchten. Andernfalls scheint es nichts zu tun.

So machen Sie eine Datei auf Unix-Plattformen ausführbar :

chmod +x myscript.py
Alejandro Quiroz
quelle
6
Danke, das hat den Trick gemacht! Es gab noch ein weiteres Problem: Der Apache-Benutzer konnte keinen Befehl im Python-Skript ausführen, aber ich konnte dies beheben, indem ich sudo verwendete und der sudoers-Datei eine Ausnahme für mein Skript hinzufügte. Danke noch einmal! :)
Verlassenes Konto
1
Ich habe das gleiche Problem wie der Apache-Benutzer. Können Sie mich bitte anleiten?
Emma
1
Ich habe Ihre Antwort verwendet, es führt das Python-Skript gut aus, aber ich kann die Ergebnisse nicht wiedergeben. Es wird nichts auf der Webseite angezeigt. Können Sie mir helfen?
Hamdi Charef
1
"#! / Usr / bin / env python" in der ersten Zeile hat mir den Trick getan. Toll!
C3PO
1
Für OSX: echo shell_exec("/usr/local/bin/python3 /Users/cyborg/Dev/magic.py"); oder:echo shell_exec("/usr/bin/python /Users/cyborg/Dev/magic.py");
Cyborg
23

Ich empfehle, passthruden Ausgabepuffer direkt zu verwenden und zu handhaben:

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

Wenn Sie den Rückgabestatus des Befehls wissen und die gesamte stdoutAusgabe erhalten möchten, können Sie Folgendes verwenden exec:

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

$outist ein Array aller Zeilen. $statusist der Rückgabestatus. Sehr nützlich zum Debuggen.

Wenn Sie auch die stderrAusgabe sehen möchten, können Sie entweder mit proc_open spielen oder einfach 2>&1zu Ihrer hinzufügen $command. Letzteres reicht oft aus, um die Dinge zum Laufen zu bringen und viel schneller zu "implementieren".

kqw
quelle
8

Alejandro hat es geschafft und die Ausnahme (Ubuntu oder Debian) klarer gemacht - ich habe nicht den Repräsentanten, der der Antwort selbst etwas hinzufügen kann:

Sudoers Datei: sudo visudo

Ausnahme hinzugefügt: www-data ALL=(ALL) NOPASSWD: ALL

Colin Miles
quelle
7
Scheint nicht effektiv zu sein, um Sudoern WWW-Daten hinzuzufügen, und gibt Apache mehr Berechtigungen, als es benötigt. Es würde ausreichen, WWW-Datenberechtigungen für das Skript zu erteilen, das Sie ausführen.
JasonRDalton
Coole Idee, könnte aber definitiv Ihr System anfällig machen. Ich stimme @JasonRDalton
Reed
6

Um zu klären, welcher Befehl je nach Situation verwendet werden soll

exec() - Führen Sie ein externes Programm aus

system() - Führen Sie ein externes Programm aus und zeigen Sie die Ausgabe an

passthru() - Führen Sie ein externes Programm aus und zeigen Sie die Rohausgabe an

Quelle: http://php.net/manual/en/function.exec.php

Agnel Vishal
quelle
4

In meinem Fall musste ich einen neuen Ordner im wwwVerzeichnis namens erstellen scripts. Innerhalb habe scriptsich eine neue Datei namens hinzugefügt test.py.

Ich habe dann sudo chown www-data:root scriptsund verwendet sudo chown www-data:root test.py.

Dann ging ich in das neue scriptsVerzeichnis und benutzte sudo chmod +x test.py.

Meine test.py Datei sieht so aus. Beachten Sie die unterschiedliche Python-Version:

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

Von PHP mache ich jetzt folgendes:

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

Und du solltest sehen: Hallo Welt!

Tim Hallman
quelle
3

Die obigen Methoden scheinen komplex zu sein. Verwenden Sie meine Methode als Referenz.

Ich habe diese beiden Dateien:

  • run.php

  • mkdir.py.

Hier habe ich eine HTML-Seite erstellt, die eine GOSchaltfläche enthält . Wenn Sie diese Taste drücken, wird ein neuer Ordner in dem Verzeichnis erstellt, dessen Pfad Sie angegeben haben.

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
quelle
1

Dies ist so trivial, wollte aber nur jedem helfen, der bereits Alejandros Vorschlag befolgt hat, aber auf diesen Fehler gestoßen ist:

sh: blabla.py: Befehl nicht gefunden

Wenn jemand auf diesen Fehler gestoßen ist, muss Alejandro eine kleine Änderung an der PHP-Datei vornehmen:

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