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
:wink:

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

Code: Alles auswählen

$ /path/to/program.sh < script.sh > output.dat
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

Code: Alles auswählen

$ /path/to/program.sh < script.sh > output.dat
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

Code: Alles auswählen

$ /path/to/program.sh < script.sh > output.dat
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.