PythonScript aus PHP ausführen und Ausgabe ausgeben
Moin zusammen,
ich habe ein Webanwendung auf PHP Basis. Mit dieser Anwendung sollen Dokumente zusammengestellt und Aufbereitet werden. Diese Aufbereitung existiert in Python.
Jetzt möchte ich gerne aus der PHP Anwendung heraus die Python Scripte zur Verarbeitung aufrufen. Dabei soll aber nicht nur das Aufrufen im Hintergrund getriggert werden, sondern es soll die Ausgabe des Python Scriptes während der Laufzeit ausgegeben werden. Die Python Scripte brauchen in der Regel immer einige Minuten, in denen Sie aber protokollieren was gerade passiert. Diese Ausgabe möchte ich dem Nutzer im Browser gerne "live zeigen".
Hat jemand einen Tipp für mich, wie so etwas funktionieren kann?
Vielen Dank vorab.
ich habe ein Webanwendung auf PHP Basis. Mit dieser Anwendung sollen Dokumente zusammengestellt und Aufbereitet werden. Diese Aufbereitung existiert in Python.
Jetzt möchte ich gerne aus der PHP Anwendung heraus die Python Scripte zur Verarbeitung aufrufen. Dabei soll aber nicht nur das Aufrufen im Hintergrund getriggert werden, sondern es soll die Ausgabe des Python Scriptes während der Laufzeit ausgegeben werden. Die Python Scripte brauchen in der Regel immer einige Minuten, in denen Sie aber protokollieren was gerade passiert. Diese Ausgabe möchte ich dem Nutzer im Browser gerne "live zeigen".
Hat jemand einen Tipp für mich, wie so etwas funktionieren kann?
Vielen Dank vorab.
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 1332856339
Url: https://administrator.de/contentid/1332856339
Ausgedruckt am: 22.11.2024 um 04:11 Uhr
2 Kommentare
Neuester Kommentar
Servus @schneerunzel,
das ist kein Problem mit etwas Ajax gewürzt lässt sich das verwirklichen. Habe dir mal ein ganz primitives "Single-Page" Beispiel dazu gebaut, im Normalfall macht man daraus zwei separate Seiten( eine für das Frontend und eine für das Backend das die Daten an das Frontend liefert). Ich möchte explizit darauf hinweisen das das so niemals live gehen sollte da hier jegliche Arten von Kommandos ausgeführt werden können für die der ausführende Prozess-User des Webservers Rechte besitzt. Das kannst du ja dann selbst auf deine Bedürfnisse einschränken was wo ausgeführt werden darf. Habe es so umgesetzt damit man selbst erst mal ein paar Kommandos ausprobieren kann ohne erst viel Variablen anpassen zu müssen.
Wichtig: Damit python Skripte die Live-Ausgabe funktioniert muss man die Ausgabe der Skripte auf unbuffered einstellen, für Shell-Skripte ist das nicht nötig die funktionieren so. Bei python erledigt das der Kommandozeilenparameter -u.
Deine Python-Skripte solltest du also folgendermaßen in der Textbox der HTML-Seite starten
Ebenso muss man beachten das der User unter dem der Webserver läuft auch Lese- und Execute Rechte auf den entsprechenden Pfad haben muss damit dieser das Skript ausführen kann. Je nachdem wo das Skript also liegt sind dazu je nach Linux-System weitere Maßnahmen wie bspw. das Anpassen von systemd Direktiven nötig.
Grüße Uwe
das ist kein Problem mit etwas Ajax gewürzt lässt sich das verwirklichen. Habe dir mal ein ganz primitives "Single-Page" Beispiel dazu gebaut, im Normalfall macht man daraus zwei separate Seiten( eine für das Frontend und eine für das Backend das die Daten an das Frontend liefert). Ich möchte explizit darauf hinweisen das das so niemals live gehen sollte da hier jegliche Arten von Kommandos ausgeführt werden können für die der ausführende Prozess-User des Webservers Rechte besitzt. Das kannst du ja dann selbst auf deine Bedürfnisse einschränken was wo ausgeführt werden darf. Habe es so umgesetzt damit man selbst erst mal ein paar Kommandos ausprobieren kann ohne erst viel Variablen anpassen zu müssen.
Wichtig: Damit python Skripte die Live-Ausgabe funktioniert muss man die Ausgabe der Skripte auf unbuffered einstellen, für Shell-Skripte ist das nicht nötig die funktionieren so. Bei python erledigt das der Kommandozeilenparameter -u.
Deine Python-Skripte solltest du also folgendermaßen in der Textbox der HTML-Seite starten
python -u /pfad/zum/script.py
<?php
// get cmd to be executed from get parameter "command"
$command = (isset($_GET['command'])) ? $_GET['command'] : "";
// if cmd is not empty
if ($command !== "" ){
// pre flush all buffers
while(@ob_end_flush());
// run command
$proc = popen("$command 2>&1",'r');
if ($proc){
// read command output line by line and flush buffer directly
while (($buffer = fgets($proc)) !== false){
echo $buffer;
@flush();
}
// close process pointer
pclose($proc);
}
}else{ // cmd is empty show html page with interface instead
?>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<script>
// init function (setup user control event handlers etc.)
function init(){
// setup click eventhandler of button
document.getElementById('btnStart').onclick = (e) => {
// call function to with command from input element with id 'txtCommand'
LiveGetCommandResult(document.getElementById('txtCommand').value);
};
}
// function to get live command output
function LiveGetCommandResult(cmd){
// reference dom element where command output will be shown
var elOutput = document.getElementById("result");
// create new ajax request object
var ajax = new XMLHttpRequest();
// index variable which holds current command output position
var curPos = 0;
// event when loading has started
ajax.onloadstart = () => {
elOutput.value = "=== Command started ===\n\n";
};
// event called on every respose update
ajax.onprogress = (e) => {
// append response part to output element
elOutput.value += ajax.responseText.substring(curPos);
// scroll to end of output element
elOutput.scrollTop = elOutput.scrollHeight;
// save current output position index
curPos = ajax.responseText.length;
};
// event called when ajax call returns an error
ajax.onerror = () => {
elOutput.value += "AJAX-ERROR: " + ajax.statusText;
};
// event on finish
ajax.onloadend = () => {
elOutput.value += "\n\n=== Command ended ===\n";
elOutput.scrollTop = elOutput.scrollHeight;
};
// setup ajax uri with "command" get parameter and URI encoded commandline
ajax.open('GET','?command=' + encodeURIComponent(cmd));
// start ajax call
ajax.send();
}
</script>
<style>
#result {
border:1px solid gray;
height:400px;
width:70%;
overflow: scroll;
}
</style>
</head>
<body onload="init()">
<input type="text" id="txtCommand" placeholder="Enter command" value="ping -c 30 -i .5 127.0.0.1" size="50" />
<button id="btnStart">Start command</button>
<textarea id="result" readonly></textarea>
</body>
</html>
<?php }
Vorschau
Grüße Uwe