2016-08-29 3 views
0

Ich schreibe eine Webanwendung, in der Benutzer versuchen können, verschiedene Programmierprobleme zu lösen. Der Benutzer lädt eine ausführbare .py-Datei hoch, und die Anwendung gibt ihr eine vorbestimmte Eingabe und überprüft, ob die Ausgabe korrekt ist. (Ähnlich wie Codeforce works)Ausführen einer Python-Datei aus Python heraus, Einspeisen der Eingabe und Abrufen der Ausgabe

Angenommen ich das Skript des Benutzers hochgeladen haben, wie kann ich das Skript des Benutzers ausführen aus meinem eigenen Python-Skript, Fütterung des Skripts Eingabe des Benutzers, die von einem normalen input() Funktion erfasst werden würde, und das Abrufen die Ausgabe von print() Funktionen, damit ich ihre Richtigkeit überprüfen kann?

+0

Was Sie versucht haben. Bitte bemühen Sie sich, Ihr Problem zu lösen, bevor Sie eine Frage stellen. Meistens wirst du am Ende dein eigenes Problem lösen. –

Antwort

1

Ich habe es herausgefunden.

Hinweis: Wenn Sie dies in einer Produktionsumgebung verwenden möchten, stellen Sie sicher, dass Sie Einschränkungen bezüglich dessen festlegen, was der Benutzer ausführen kann.

executor.py

import subprocess 

# create process 
process = subprocess.Popen(
     ['python3.4','script_to_execute.py'], # shell command 
     stdin=subprocess.PIPE, 
     stdout=subprocess.PIPE, 
     stderr=subprocess.PIPE 
) 

# encode string into bytes, since communicate function only accepts bytes 
input_data = "Captured string".encode(encoding='UTF-8') 

# send the input to the process, retrieve output of print() function 
stdoutdata, stderrdata = process.communicate(input=input_data) 

# decode output back into string 
output_data = stdoutdata.decode(encoding='UTF-8') 

print(output_data) 

script_to_execute.py

input_data = input() 

print("Input recieved!\nData: " + input_data) 

Ausgabe von executor.py

Input recieved! 
Data: Captured string 
+4

Wenn Sie ein Skript ausführen, das jemand hochgeladen hat, können Sie die Sekunden zählen, bis Ihr Server etwas Schlechtes tut. Sie sollten den Subprozess zumindest in einem eingeschränkten Benutzerkonto starten. –

+0

... oder ein virtualenv. – boardrider

+1

Wenn Sie "universal_newlines = True" an den "Popen" -Konstruktor übergeben, können Sie "str" ​​und "str" ​​ohne explizite Kodierung an "bytes" oder Dekodierung von "bytes" übergeben; 'communicate' nimmt' str' als Argument und gibt ein Zwei-Tupel von 'str' zurück. Wohlgemerkt, es benutzt die Kodierung, die von 'locale.getpreferredencoding (False)' zurückgegeben wird. Auf manchen Rechnern (besonders in Windows, wo es normalerweise etwas Schreckliches wie 'cp1252' anstelle von 'utf-8') gibt, solltest du explizit bleiben 'encodieren' und' decodieren' Schritte. – ShadowRanger

Verwandte Themen