Seite 1 von 3
os.system abwarten
Verfasst: Dienstag 10. Mai 2011, 14:01
von mzh
Hallo zusammen
Wenn ich in einem Programm mit os.system einen Befehl auf dem System ausführe (weil bspw. ein anderes Programm ein paar Daten produzieren muss, die ich mit dem aufrufenden Pythonskript bearbeiten will), dann scheint es mir so, als ob das Skript nicht darauf wartet bis das externe Programm zu Ende ist, sondern einfach weiter seine Instruktionen abarbeitet.
Wie kann ich erreichen, dass das Skript darauf wartet, dass das Programm das ich unter os.system starte auch wirklich beendet, bevor das Skript fortsetzt?
Vielen Dank für Hinweise.
Re: os.system abwarten
Verfasst: Dienstag 10. Mai 2011, 14:10
von Hyperion
Indem Du das subprocess-Modul verwendest

Re: os.system abwarten
Verfasst: Dienstag 10. Mai 2011, 14:12
von EyDu
Hallo,
in der
Dokumentation steht das eine oder andere Wort dazu. Interessant für dich ist auch der letzte Absatz mit dem Hinweis auf das subprocess-Modul. Das ist deutlich umfangreicher und sollte ``os.system`` vorgezogen werden.
Sebastian
Re: os.system abwarten
Verfasst: Dienstag 10. Mai 2011, 16:09
von mzh
Wie schreibe ich dann einen korrekten Befehl für subprocess.call?
Wenn der os.system Befehl so aussieht:
Code: Alles auswählen
os.system(self.vmd -dispdev text -eofexit < getCOM.vmd > ./sandbox/vmd-%s-com.log' % self.target)
?
Re: os.system abwarten
Verfasst: Dienstag 10. Mai 2011, 16:39
von problembär
mzh hat geschrieben:Code: Alles auswählen
os.system(self.vmd -dispdev text -eofexit < getCOM.vmd > ./sandbox/vmd-%s-com.log' % self.target)
Wenn Dein os.system-Befehl so aussieht, dann hast Du ein ganz anderes Problem: os.system() erwartet einen String. "self.vmd" kann eine Variable sein, aber dann müßte danach ' + "diesunddas" ' oder sowas kommen.
Re: os.system abwarten
Verfasst: Dienstag 10. Mai 2011, 17:06
von mzh
Ja, sorry das ist falsch abgetippt. Das Argument von os.system ist natürlich ein String.
Also, wie würde ich also den folgenden Befehl in subprocess.call übergeben? Ich hab vor allem Schwierigkeiten die Umleitungsklammern richtig mitzuteilen.
Code: Alles auswählen
os.system(self.vmd + ' -dispdev text -eofext < getCOM.vmd > ./sandbox/vmd-%s-com.log' % self.target)
wobei self.vmd auch ein String ist.
Ich habs mal an einer anderen Stelle versucht. Ursprünglich sah es so aus:
Code: Alles auswählen
os.system('./realign.py ../x_output/' + target[0:4] + '-out.pqr')
Nun habe ich, in Anlehnung an die Dokumentation zu subprocess folgendes probiert:
Code: Alles auswählen
p = subprocess.Popen('./realign.py ../x_output/' + target[0:4] + '-out.pqr')
Allerdings erhalte ich folgende Meldung:
Code: Alles auswählen
'No such file or directory'
<!-- The above is a description of an error in a Python program, formatted
for a Web browser because the 'cgitb' module was enabled. In case you
are not reading this in a Web browser, here is the original traceback:
Traceback (most recent call last):
File "/home/mzhpropka/public_html/a_content/runPDB2PQR.cgi", line 63, in ?
p = subprocess.Popen('./realign.py ' +\
File "/usr/lib/python2.4/subprocess.py", line 542, in __init__
errread, errwrite)
File "/usr/lib/python2.4/subprocess.py", line 975, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
-->
Re: os.system abwarten
Verfasst: Dienstag 10. Mai 2011, 18:00
von problembär
Also, ich glaube, das Problem sind die Ausgabeumlenkungen, die da in dem Shell-Befehl sind.
Ich würde stattdessen über "os.popen()" die Ausgabe in das Python-Skript einlesen und von dort, also in Python, in eine log-Datei schreiben.
Auch das Einlesen über "<" würde ich eher in Python umsetzen.
Re: os.system abwarten
Verfasst: Dienstag 10. Mai 2011, 18:09
von BlackJack
@problembär: Aber bitte mit `subprocess` anstelle von `os.popen()`.
Re: os.system abwarten
Verfasst: Dienstag 10. Mai 2011, 18:13
von problembär
Re: os.system abwarten
Verfasst: Dienstag 10. Mai 2011, 18:44
von mzh
BlackJack hat geschrieben:@problembär: Aber bitte mit `subprocess` anstelle von `os.popen()`.
eben, also so
Code: Alles auswählen
p = subprocess.Popen('./realign.py ../x_output/' + target[0:4] + '-out.pqr')
?
Re: os.system abwarten
Verfasst: Dienstag 10. Mai 2011, 19:01
von BlackJack
@mzh: Eher so wie in der Dokumentation beschrieben.
Re: os.system abwarten
Verfasst: Donnerstag 12. Mai 2011, 17:34
von mzh
@blackjack:
In der Dokumentation steht das folgende:
Code: Alles auswählen
sts = os.system("mycmd" + " myarg")
==>
p = Popen("mycmd" + " myarg", shell=True)
sts = os.waitpid(p.pid, 0)[1]
was sind "mycmd" und "myarg"? Sind das Namen von Skripten? Oder Variablennamen von eingelesenen Skripten?
Was ich nicht aus der Dokumentation erkennen kann ist, wie man Umleitungen von Ausgaben am besten umsetzt, da wäre ich sehr froh um Hinweise.
Re: os.system abwarten
Verfasst: Donnerstag 12. Mai 2011, 17:59
von cofi
mzh hat geschrieben:was sind "mycmd" und "myarg"? Sind das Namen von Skripten? Oder Variablennamen von eingelesenen Skripten?
Wie kommst du denn darauf? Das sind Strings, nicht mehr, aber auch nicht weniger. Sinnvollerweise ist `myarg` ein Programm und `myarg` sind Argumente.
Ich bin mit dem Beispiel aber ueberhaupt nicht gluecklich, da es nicht die Alternative ohne `shell` aufzeigt *bugreport schreiben notier*.
Was du verwenden solltest ist:
Code: Alles auswählen
p = subprocess.Popen(['path/to/program', 'arg1', 'arg2'],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
stdin=subprocess.PIPE)
stdout, stderr = p.communicate(input)
Wobei du std* nur uebergeben musst wenn du es brauchst, genauso musst du communicate kein `input` uebergeben, wenn du stdin nicht brauchst. Aber du solltest wirklich die Dokumentation lesen _und verstehen_.
Re: os.system abwarten
Verfasst: Freitag 13. Mai 2011, 08:37
von mzh
cofi hat geschrieben:
Code: Alles auswählen
p = subprocess.Popen(['path/to/program', 'arg1', 'arg2'],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
stdin=subprocess.PIPE)
stdout, stderr = p.communicate(input)
@ cofi: danke für das Beispiel.
Was ich allerdings nirgends finden kann ist wie ich mit den Umleitungen '<' und '>' umgehen soll.
Wenn ich auf der Shell also
schreiben würde, würde das dann mit subprocess.Popen
so aussehen?
Code: Alles auswählen
p = subprocess.Popen(['/path/to/program.sh', 'script.sh', 'output.dat'],
stdin='script.sh',
stdout='output.dat'
Re: os.system abwarten
Verfasst: Freitag 13. Mai 2011, 08:59
von cofi
mzh hat geschrieben:Wenn ich auf der Shell also
schreiben würde, würde das dann mit subprocess.Popen
so aussehen?
Code: Alles auswählen
p = subprocess.Popen(['/path/to/program.sh', 'script.sh', 'output.dat'],
stdin='script.sh',
stdout='output.dat'
Nein. Ungetestet(evtl sind die nested with's falsch):
Code: Alles auswählen
with open('script.sh'), open('output.dat', w) as in, out:
p = subprocess.Popen(['/path/to/program.sh'],
stdin=in,
stdout=out)
Re: os.system abwarten
Verfasst: Freitag 13. Mai 2011, 09:06
von mzh
cofi hat geschrieben:mzh hat geschrieben:Wenn ich auf der Shell also
schreiben würde, würde das dann mit subprocess.Popen
so aussehen?
Code: Alles auswählen
p = subprocess.Popen(['/path/to/program.sh', 'script.sh', 'output.dat'],
stdin='script.sh',
stdout='output.dat'
Nein. Ungetestet(evtl sind die nested with's falsch):
Code: Alles auswählen
with open('script.sh'), open('output.dat', w) as in, out:
p = subprocess.Popen(['/path/to/program.sh'],
stdin=in,
stdout=out)
ich hab mir das eben gedacht, dass es wahrscheinlich so sein soll... und ist 'in' nicht ein keyword? Danke jedenfalls.
Re: os.system abwarten
Verfasst: Freitag 13. Mai 2011, 09:20
von mzh
Code: Alles auswählen
p = subprocess.Popen([self.vmd, '-dispdev text', '-eofexit'],
stdin=comScript,
stdout='./sandbox/vmd-%s-com.log' % self.target)
tja, wäre schön gewesen
Code: Alles auswählen
Traceback (most recent call last):
File "/home/mzhpropka/public_html/a_content/runPDB2PQR.cgi", line 44, in ?
ctrAlgn.writeCOM()
File "/home/mzhpropka/public_html/a_content/realign.py", line 81, in writeCOM
stdout='./sandbox/vmd-%s-com.log' % self.target)
File "/usr/lib/python2.4/subprocess.py", line 533, in __init__
(p2cread, p2cwrite,
File "/usr/lib/python2.4/subprocess.py", line 830, in _get_handles
p2cread = stdin.fileno()
AttributeError: 'str' object has no attribute 'fileno'
Re: os.system abwarten
Verfasst: Freitag 13. Mai 2011, 10:15
von EyDu
Würdest du die Dokumentation lesen, dann wüsstest du auch, warum das nicht funktionieren kann:
http://docs.python.org/library/subprocess.html hat geschrieben:stdin, stdout and stderr specify the executed programs’ standard input, standard output and standard error file handles, respectively. Valid values are PIPE, an existing file descriptor (a positive integer), an existing file object, and None.
Re: os.system abwarten
Verfasst: Freitag 13. Mai 2011, 10:20
von cofi
mzh hat geschrieben:ich hab mir das eben gedacht, dass es wahrscheinlich so sein soll... und ist 'in' nicht ein keyword? Danke jedenfalls.
Ja, `in` ist ein Keyword. Das musst du dann eben durch `in_` ersetzen.
Und wenn du dir gedacht hast, dass es "wahrscheinlich so sein soll", warum machst du es in deinem Versuch dann nicht so?
Re: os.system abwarten
Verfasst: Freitag 13. Mai 2011, 14:34
von syntor
EyDu hat geschrieben:Würdest du die Dokumentation lesen, dann wüsstest du auch, warum das nicht funktionieren kann:
http://docs.python.org/library/subprocess.html hat geschrieben:stdin, stdout and stderr specify the executed programs’ standard input, standard output and standard error file handles, respectively. Valid values are PIPE, an existing file descriptor (a positive integer), an existing file object, and None.
Oder ganz einfach cofi's Beispiel beachten.