windows interaktiver subprocess kein output

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
init-0
User
Beiträge: 38
Registriert: Samstag 22. Januar 2011, 18:46

Hi,

ich würde gerne einen wrapper für die commandline schreiben und benutze dafür subprocess.Popen.
Dabei bekomme ich bei manchen interaktiven Prozessen keinen Output:

Code: Alles auswählen

from subprocess import Popen, PIPE
import os

cmd="python" # -u funktioniert auch nicht

p = Popen(cmd, stdout=PIPE, stderr=PIPE, stdin=PIPE, shell=False,
          bufsize=0, env=os.environ.copy(), start_new_session=True)


#p.stdout.flush()
p.stdin.write(b"print(123)\n")
p.stdin.flush()
print("reading...")
print(p.stdout.read(1))
print("done")
Bleibt beim reading hängen:

Code: Alles auswählen

reading...
Selbst wenn ich den Prozess danach abbreche, bekomme ich einen leeren string von stdout und stderr
Wenn ich einen SyntaxFehler einbaue, bekomme ich wenigstens output für stderr

Code: Alles auswählen

p.stdin.write(b"asdf asdf\n")

Code: Alles auswählen

reading...
b''
done
b'  File "<stdin>", line 1\r\n    asdf asdf\r\n            ^\r\nSyntaxError: invalid syntax\r\n'
Das Problem habe ich nicht wenn ich cmd als Prozess benutze. Wenn ich aber bash benutze, bekomme ich nur den Output des in stdin geschriebenen Befehls, und kein Prompt etc.
Ich vermute, dass es daran liegt, dass Python den Output buffered, aber die -u Option hilft hierbei auch nicht.

Hat jemand eine Idee, wie man das auf Windows lösen kann?
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Was genau ist denn der Hintergrund? Einzelne Kommandos kann man per python -c "dein kommando; und noch eins" an den Interpreter schicken. Das ist wahrscheinlich einfacher, zumal du ja schreibst dass du eh keinen Python-Prompt haben willst (wenn ich dich richtig verstanden habe).
__deets__
User
Beiträge: 14523
Registriert: Mittwoch 14. Oktober 2015, 14:29

Hast du mal die communicate Methode versucht?
init-0
User
Beiträge: 38
Registriert: Samstag 22. Januar 2011, 18:46

__deets__ hat geschrieben: Montag 10. Dezember 2018, 19:14 Hast du mal die communicate Methode versucht?
die wartet dann auf abschluss des prozesses, das funktioniert bei interaktiven prozessen allerdings nicht, weil die sich nach einer eingabe nicht beenden.
snafu hat geschrieben: Montag 10. Dezember 2018, 18:41 Was genau ist denn der Hintergrund? Einzelne Kommandos kann man per python -c "dein kommando; und noch eins" an den Interpreter schicken. Das ist wahrscheinlich einfacher, zumal du ja schreibst dass du eh keinen Python-Prompt haben willst (wenn ich dich richtig verstanden habe).
Ich will den Output vom Prozess in ein Window schreiben, und von dem Fenster Input zu bekommen, also will ich das Prompt schon auslesen. Im Grunde will ich nur ein neues GUI für verschiedene Shells programmieren. Deshalb will ich jeden Output direkt lesen können und gleichzeitig Input schreiben.
__deets__
User
Beiträge: 14523
Registriert: Mittwoch 14. Oktober 2015, 14:29

Dann schau dir mal das Modul pexpect an.
Sirius3
User
Beiträge: 17738
Registriert: Sonntag 21. Oktober 2012, 17:20

Eine Shell ist halt viel mehr, als nur Input/Output. Dazu mußt Du eine mehr oder weniger vollständige Terminalemulation schreiben. Das Modul pexpect macht sowas ähnliches.
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Aber AFAIK ist pexpect dafür nur unter Linux und ähnlichen Systemen geeignet. Für Windows, wovon ja hier die Rede ist, gibt es nur eingeschränkte Funktionalität, da Windows keine Pseudo-Terminals kennt.
__deets__
User
Beiträge: 14523
Registriert: Mittwoch 14. Oktober 2015, 14:29

Eingeschränkt ist immer noch mehr als keine. Ich kenne ich da gerade unter Windows nicht wirklich aus, aber da es explizit unterstützt wird, kann es ja sein, dass es ausreicht.
init-0
User
Beiträge: 38
Registriert: Samstag 22. Januar 2011, 18:46

Sirius3 hat geschrieben: Montag 10. Dezember 2018, 19:42 Eine Shell ist halt viel mehr, als nur Input/Output. Dazu mußt Du eine mehr oder weniger vollständige Terminalemulation schreiben. Das Modul pexpect macht sowas ähnliches.
Ja aber beim cmd.exe funktioniert es ja und die wichtigen Keybindings kann ich ja manuell weiterleiten. Momentan will ich erstmal den Output von allen Prozessen haben.
snafu hat geschrieben: Montag 10. Dezember 2018, 19:48 Aber AFAIK ist pexpect dafür nur unter Linux und ähnlichen Systemen geeignet. Für Windows, wovon ja hier die Rede ist, gibt es nur eingeschränkte Funktionalität, da Windows keine Pseudo-Terminals kennt.
Ja, hab grade mal das was davon unter Windows läuft probiert und hier funktioniert es auch nicht:

Code: Alles auswählen

>>> import pexpect.popen_spawn as spawn
>>> dir(spawn)
['EOF', 'Empty', 'PY3', 'PopenSpawn', 'Queue', 'SpawnBase', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'os', 'shlex', 'signal', 'string_types', 'subprocess', 'sys', 'threading', 'time']
>>> p = spawn.PopenSpawn("python", timeout=30*60)
>>> p.read_nonblocking(10, 5)
b''
Antworten