Python: *.bat mit subprocess - Fehlerrückgabe (Windows - Kubuntu)

44 views
Skip to first unread message

Ronny

unread,
Aug 18, 2010, 6:14:51 AM8/18/10
to Hamburg Python User Group
Hallo.

Ich habe da ein kleines Problem. Ich bin gerade dabei ein Python-
Programm zu schreiben, welches übers Netzwerk eine Datei ausführt und
etwas zurück gibt.
Und zwar läuft auf einem Windows XP die server.py die
folgendermaßen aussieht:

from socket import *
#from subprocess import Popen
#from subprocess import *
import time, os, subprocess

s = socket(AF_INET, SOCK_STREAM)
s.bind(("",8888))
s.listen(5)

client, addr = s.accept()
print "Verbindung von", addr, "erhalten"

try:
while 1:
data = client.recv(1024)

if data.startswith('Befehl'):
batch_file = 2
client.send(data)

elif data == 'start_good':
batch_file = os.system("good.bat")
if batch_file == 0:
client.send("Die Datei wurde erfolgreich
ausgefuehrt.")

#data = Popen("good.bat")
#print data

#text = data.read()
#print text
#client.send("jo")

#data = os.popen("good.bat", 'r')
#text = data.read()
#print text
#client.send(text)


elif data == 'start_bad':
#batch_file = os.system("bad.bat")
#if batch_file == 1:
# client.send("Fehler beim ausfuehren der Datei!")


print "Step1"
#testtest = subprocess.Popen(["bad.bat"],
stdout=subprocess.PIPE)
testtest = subprocess.Popen(["bad.bat"],
stdout=testtest.PIPE)
print "Step2"
testtest.wait()
print "Step3"
testtest = testtest.stdout.read()
print testtest


#data = Popen("bad.bat")
#testdaten = Popen(['cmd.exe','/C','bad.bat'],
stdout=subprocess.PIPE).communicate()[0]
#client.send("jo")
#print testdaten
#print data.communicate()


#p = Popen(['bad.bat'], stdout=PIPE, stderr=PIPE)
#output, errors = p.communicate()
#p.wait()

#data = os.popen("bad.bat", 'r')
#text = data.read()
#print text
#client.send(text)

else:
client.send("Eingabe: "+data)
except:
try:
client, addr=s.accept()
error_msg = "Das Programm wurde unterbrochen"
print error_msg
client.send(error_msg)
client.close()
except:
print "Fehler"
client.close()
finally:
client, addr=s.accept()
final_str = "Das Programm wurde beendet"
client.send(final_str)
client.close()



Und auf meinem Kubuntu läuft die client.py


from socket import *

s = socket(AF_INET, SOCK_STREAM)
s.connect(("xxx.xx.x.xxx",8888))

while 1:
nachricht = raw_input("Nachricht: ")
s.send(nachricht)
tm = s.recv(1024)
print tm
if nachricht == 'exit':
break

s.close()



Die Kommunikation funktioniert soweit. Die Übertragung von Befehlen an
die server.py klappt und die server.py gibt auch "Antworten" an die
client.py. Soweit, so gut.
Er gibt mir aber keine Fehler zurück, falls die .bat-Dateien einen
auswerfen. Ich bin da schon seit anderthalb Tagen am googeln und habe
diverse Sachen ausprobiert (Welche auch teilweise im Code
auskommentiert sind). Aber er liefert nie etwas zurück. Er bleibt
immer stehen. Aktuell (siehe Code server.py) gibt der Server "Step1"
aus und dann hängt er bzw. bleibt einfach stehen und der Client wartet
auf eine Antwort.

Kann mir jemand helfen und sagen, woran das liegt, was ich falsch
mache und/oder wie ich es richtig mache? :( Wäre wirklich sehr Dankbar
dafür.

Hier noch die bad.bat:

CD %0\..
@echo off
ping -n 1 localhost> nul
echo jetzt kommt der fehler!
cd ä:
aidaihsdiahd


Vielen herzlichen Dank im Voraus
Ronny

Christopher Arndt

unread,
Aug 18, 2010, 7:50:48 AM8/18/10
to hamburg-p...@googlegroups.com
Ronny schrieb:

> Ich bin gerade dabei ein Python-
> Programm zu schreiben, welches übers Netzwerk eine Datei ausführt und
> etwas zurück gibt.

Erstmal grundsätzlich die Frage: warum benutzt du nicht einen
bestehenden RPC-Mechanismus wie XML-RPC? Da brauchst du den ganzen
Netzwerkcode nicht selbst schreiben, alles was du brauchst, ist schon in
diesen beiden Modulen der Standardlibrary enthalten:

http://docs.python.org/library/simplexmlrpcserver.html
http://docs.python.org/library/xmlrpclib.html

> Aktuell (siehe Code server.py) gibt der Server "Step1"
> aus und dann hängt er bzw. bleibt einfach stehen und der Client wartet
> auf eine Antwort.
>

> echo jetzt kommt der fehler!
> cd ä:

Ich vermute mal, das Batchskript wartet nach dem "cd ä:" Befehl auf eine
Eingabe ("Wiederholen/Ignorieren/Abbrechen?"), die dein Aufruf mit
Subprocess nicht liefert. Deshalb hängt testtest.wait(). Probier mal,
bei subprocess.Popen(), stdin=subprocess.PIPE zu übergeben und dann mit
communicate() ein 'y' an das Batchskript zu schicken.

Kommunikation mit Prozessen über Filehandles ist ein delikate Sache.
Unter POSIX-System gibt es dafür pexpect, das funktioniert unter Windows
aber nur mit Cygwin.

Chris

Ronny

unread,
Aug 18, 2010, 9:17:17 AM8/18/10
to Hamburg Python User Group
ok es lag wohl doch am stdin.

Der Code sieht jetzt so aus:

elif data == 'start_bad':
testtest = subprocess.Popen(["bad.bat"], stdout=subprocess.PIPE,
stdin=subprocess.PIPE)

client.send('jo')


Nun gibt die server.py in der Windows-Konsole alles ungleich "echo"
aus:

Das System kann das angegebene Laufwerk nicht finden.
Der Befehl "aidaihsdiahd" ist entweder falsch geschrieben oder konnte
nicht gefunden werden.


Es fehlt jetzt aber die Ausgabe "jetzt kommt der fehler!"

Und wie ich diese ausgegebenen Fehler jetzt an meinen Client wieder
zurück schicken kann habe ich auch noch nicht heraus gefunden :(

Christopher Arndt

unread,
Aug 18, 2010, 10:09:43 AM8/18/10
to hamburg-p...@googlegroups.com
Ronny schrieb:

> Und wie ich diese ausgegebenen Fehler jetzt an meinen Client wieder
> zurück schicken kann habe ich auch noch nicht heraus gefunden :(

Wie gesagt, verwende die Methode communicate() statt send() und read(),
die kümmert sich auch noch um das Schließen der Filehandles. Evtl. musst
auch noch stderr=subprocess.Popen setzen, um an die Fehlerausgabe zu
kommen. Ich empfehle dir außerdem eine genaue, vollständige Lektüre der
Doku zu subprocess inkl. Beispielen.

Chris

Ronny

unread,
Aug 18, 2010, 10:29:16 AM8/18/10
to Hamburg Python User Group
Vielen Dank. Ich habe es hin bekommen. :)

Das ganze sieht jetzt so aus:

elif data == 'start_bad':
testtest = subprocess.Popen(["bad.bat"], stdout=subprocess.PIPE,
stdin=subprocess.PIPE, stderr=subprocess.PIPE)
client_out, client_err = testtest.communicate()
return_string = client_out+client_err
client.send(return_string)

Gruß
Ronny
Reply all
Reply to author
Forward
0 new messages