Seite 1 von 1
subprocess stdin
Verfasst: Donnerstag 1. August 2013, 14:03
von zweig1971
Hallo,
ich hab da ein kleinen Problem mit python,
Ich möchte über python ein shell script in linux ausführen.
Das shell script generiert Normale Nachrichten & Fehlermeldungen.
Code: Alles auswählen
#test_script.sh
#!/bin/bash
echo "Hello this is a normal message"
echo "Hello this is an error message, error error" >&2 #stderr kanal
read "Everything good (y/n): " ans
if [ "$ans" == "y" ]; then
echo "...then everything is okey..."
else
echo "...this is boring..."
fi
okay das geht ja bekanntlich mit subprocess
Code: Alles auswählen
path = "[...]/test_script.sh"
process = subprocess.Popen([path], stderr=subprocess.PIPE, stdout = subprocess.PIPE, stdin = subprocess.PIPE)
process.wait()
print "normal text :",process.stdout.read()
print "error text :",process.stderr.read()
aber was mache ich mit der (y/n) Abfrage im shell script ?
Normalerweise würde ich jetzt sagen :
shell script:
read -p "Everything good (y/n): " ans >&0
in python:
process.stdin.read()
aber das funktioniert nicht. Wenn ich unter python data=process.communicate(input='y\n')[0] anwende bleibt das python script hängen...
kann jemand helfen ?
danke & Gruß
zweig1971
Re: subprocess stdin
Verfasst: Donnerstag 1. August 2013, 14:24
von Sirius3
@zweig1971: Nach stdin schreibt man, "process.stdin.write(...)", und ich hoffe Du benutzt "communicate" statt "wait" und "stdout.read".
Ansonsten solltest Du genau beschreiben, was Du machst.
Re: subprocess stdin
Verfasst: Donnerstag 1. August 2013, 14:29
von BlackJack
@zweig1971: Erstmal ist der `wait()`-Aufruf problematisch. Den darfst Du nicht machen solange Du noch erwartest, dass das externe Programm irgendwelche Ausgaben macht, denn dann kann es passieren, dass alles hängen bleibt wenn der oder die Puffer zwischen den beiden Prozessen voll sind. Das externe Programm wartet dann darauf das Dein Programm die Ausgaben abnimmt, damit es weiter schreiben kann, während Dein Programm darauf wartet, dass das externe Programm endlich zum Ende kommt. Was es aber nicht kann solange es seine Ausgaben nicht los wird. Klassische Verklemmung.
Ähnliches gilt für das erste `read()` — da kann es sein, dass eine Verklemmung entsteht weil das erste `read()` auf alle Daten im ersten „Kanal” wartet, während das externe Programm darauf wartet dass Du endlich die Daten auf dem zweiten „Kanal” abnimmst. Und wieder warten beide aufeinander bis zum Sankt Nimmerleinstag.
Wenn ich das Shell-Skript korrigiere — da fehlt ein ``-p`` beim ``read`` — dann funktioniert `communicate()` bei mir.
Re: subprocess stdin
Verfasst: Freitag 2. August 2013, 12:36
von zweig1971
Hallo,
vielen dank für die Tips.
Ich hatte das nicht verstanden mit dem read & communicate. Die read Anweisungen blockierten sich tatsächlich gegenseitig.
Ich hab mir daraufhin die Anweisung communicate noch mal genauer angeschaut und jetzt verstehe ich es (so ungefähr).
mit python code :
print process.communicate('y')
bekommt man :
('Hello this is a normal message\n...then everything is okey...\n', 'Hello this is an error message, error error\n')
wie ich das jetzt verwursten soll ist mir noch nicht so klar, aber das ist ein anderes Problem...
vielen dank !
Re: subprocess stdin
Verfasst: Samstag 3. August 2013, 01:49
von Leonidas
Das ist ein ganz normales Tupel, was du da zeigst, das sollte sich genau wie andere Tupel auch verarbeiten lassen. Auch wenn ich es hochgradig seltsam finde dass da bei dir ein Tupel rausfällt.
Re: subprocess stdin
Verfasst: Samstag 3. August 2013, 10:07
von Sirius3
@Leonidas: »communicate« liefert immer ein Tulpe (stdout, stderr) zurück, würde etwas anderes da stehen, fände ich es hochgradig seltsam.
Re: subprocess stdin
Verfasst: Samstag 3. August 2013, 12:21
von Leonidas
Sirius3 hat geschrieben:@Leonidas: »communicate« liefert immer ein Tulpe (stdout, stderr) zurück, würde etwas anderes da stehen, fände ich es hochgradig seltsam.
War schon spät

Dachte das wäre die Ausgabe von einem Channel der ein in Zeilen gesplittetes Tupel ist.
Re: subprocess stdin
Verfasst: Mittwoch 7. August 2013, 09:22
von zweig1971
Hallo,
sehe ich das richtig, das wenn ich communicate benutze, ich die Antwort auf fragen vom script schon vorher wissen muß ?
was mache ich, wenn mir das script unbekannt ist ?
ich hab mir communicate in subprocess.py angeschaut. Es besteht ja im wesentlichen aus drei Teilen :
Code: Alles auswählen
if p.stdin:
print "I am in stdin"
p.stdin.write('y')
p.stdin.close()
if p.stdout:
print "I am in stdout"
print p.stdout.read()
p.stdout.close()
if p.stderr:
print "I am in stderr"
print p.stderr.read()
p.stderr.close()
Ich würde jetzt erst mal Text von p.stdout.read nach einen Fragezeichen suchen und wenn ich eins gefunden habe, den Benutzer eine Eingabe anbieten und diese dann an p.stdin.write weitergeben.
Das geht leider nicht, da scheinbar immer erst stdin abgearbeitet werden muß bevor ich an stdout und stderr drankomme, ist das richtig ?
danke & Gruß
zweig1971
Re: subprocess stdin
Verfasst: Mittwoch 7. August 2013, 10:10
von Sirius3
@zweig1971: ganz richtig. »communicate« deckt halt nur einen (recht häufigen) Spezialfall ab. Willst Du wirklich mit einem anderen Prozeß Frage-Antwort-Kommunizieren mußt Du Dich selbst darum kümmern, Daten zu lesen und zu schreiben, oder Du nutzt ein Modul wie »pexpect« das Dir einige Probleme umgehen hilft.