Seite 2 von 3
Re: os.system abwarten
Verfasst: Sonntag 15. Mai 2011, 15:17
von mzh
Ich glaub ich habs jetzt endlich mehr oder weniger hingekriegt. Macht die folgende Art das externe Programm auszuführen ungefähr Sinn?
Code: Alles auswählen
>>> vmdCmd
'/home/mzhpropka/software/vmd-bin-dir/vmd'
>>> vmdInp
'/home/mzhpropka/public_html/a_content/sandbox/vmd_test.vmd'
>>> p2 = subprocess.Popen(vmdCmd + ' -dispdev text' + ' < ' + vmdInp, shell=True)
>>> Info) VMD for LINUX, version 1.8.7 (August 1, 2009)
Info) http://www.ks.uiuc.edu/Research/vmd/
Info) Email questions and bug reports to vmd@ks.uiuc.edu
Info) Please include this reference in published work using VMD:
Info) Humphrey, W., Dalke, A. and Schulten, K., `VMD - Visual
Info) Molecular Dynamics', J. Molec. Graphics 1996, 14.1, 33-38.
Info) -------------------------------------------------------------
Info) Multithreading available, 1 CPU detected.
Info) Free system memory: 746MB (74%)
Info) No CUDA accelerator devices available.
invalid command name "-dispdev"
/home/mzhpropka/software/vmd-lib-dir/scripts/tcl8.5 /home/mzhpropka/software/vmd-lib-dir/scripts /home/mzhpropka/software/lib /Projects/johns/tcl/8.5.6/lib_LINUX/lib /home/mzhpropka/software/vmd-lib-dir/scripts/vmd /home/mzhpropka/software/vmd-lib-dir/plugins/LINUX/tcl /home/mzhpropka/software/vmd-lib-dir/plugins/noarch/tcl /home/mzhpropka/software/vmd-lib-dir/scripts/la1.0
/home/mzhpropka/software/vmd-lib-dir/scripts/tcl8.5 /home/mzhpropka/software/vmd-lib-dir/scripts /home/mzhpropka/software/lib /Projects/johns/tcl/8.5.6/lib_LINUX/lib /home/mzhpropka/software/vmd-lib-dir/scripts/vmd /home/mzhpropka/software/vmd-lib-dir/plugins/LINUX/tcl /home/mzhpropka/software/vmd-lib-dir/plugins/noarch/tcl /home/mzhpropka/software/vmd-lib-dir/scripts/la1.0 /home/mzhpropka/software/vmd-lib-dir/scripts/orient
VMD is loading the file
Info) Using plugin pdb for structure file 1AVD.pdb
Info) Using plugin pdb for coordinates from file 1AVD.pdb
Info) Determining bond structure from distance search ...
Info) Finished with coordinate file 1AVD.pdb.
Info) Analyzing structure ...
Info) Atoms: 2022
Info) Bonds: 2026
Info) Angles: 0 Dihedrals: 0 Impropers: 0 Cross-terms: 0
Info) Bondtypes: 0 Angletypes: 0 Dihedraltypes: 0 Impropertypes: 0
Info) Residues: 287
Info) Waters: 37
Warning) Unusual bond between residues: 17 (protein) and 600 (none)
Info) Segments: 1
Info) Fragments: 41 Protein: 2 Nucleic: 0
0
atomselect0
Info) Opened coordinate file 1AVD-rew.pdb for writing.
Info) Finished with coordinate file 1AVD-rew.pdb.
Info) VMD for LINUX, version 1.8.7 (August 1, 2009)
Info) Exiting normally.
>>>
Wenn ich allerdings 'shell=False' setze, dann kriege ich
Code: Alles auswählen
Traceback (most recent call last):
File "<stdin>", line 1, in ?
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
>>>
und in der Dokumentation steht, dass 'shell' normalerweise nicht benötigt wird. Woran kann es liegen, dass der Befehl bei mir nur mit 'shell=True' funktioniert?
Re: os.system abwarten
Verfasst: Sonntag 15. Mai 2011, 15:26
von EyDu
Da du offensichtlich nicht liest und umsetzt was andere schreiben, solltest du einfach den Thread noch einmal von vorne durcharbeiten und die Beiträge vestehen und entsprechend auf dein Problem anwenden.
Re: os.system abwarten
Verfasst: Montag 16. Mai 2011, 08:42
von mzh
Ich habe jetzt versucht soviel zu dem Thema zu verstehen wie möglich und dazu auch einige simple Beispiele versucht.
Bspw. das folgende:
Ich will mir den Inhalt des Verzeichnisses anzeigen lassen. Die Anzeige wird in ein File 'lsout.dat' umgeleitet.
Der Shellbefehl 'ls' steht in einem File 'lsCmd.sh'. Für 'ls' soll die '-l' Option verwendet werden.
Das 'lsCmd.sh' File sieht so aus:
Nun der Pythonteil:
Code: Alles auswählen
import subprocess
lsproc = subprocess.Popen(['./lsCmd.sh'], stdout=subprocess.PIPE, shell=False)
lsout = open('lsout.dat', 'w')
lsout.write(lsproc.stdout.read())
lsout.close()
Im 'lsout.dat' File steht nun der Inhalt des Verzeichnisses. In meinem Fall sieht es so aus, dass ich ein Programm starten möchte, welches dann ein File mit Anweisungen ausführt, bspw. gnuplot.
Das Anweisungs-File 'sin_cos.gnu' könnte so aussehen:
Code: Alles auswählen
set terminal postscript;
set output 'sin_cos.ps';
plot sin(x), cos(x);
quit;
Auf der Shell würde ich das so aufrufen:
So erhalte ich das 'sin_cos.ps' File.
Mit subprocess.Popen würde ich das jetzt so machen:
Code: Alles auswählen
import subprocess
gnup = subprocess.Popen(['gnuplot', 'sin_cos.gnu'], shell=False)
Das schreibt mir das 'sin_cos.ps' File. Ich versuche das jetzt auf meine Situation anzuwenden.
Re: os.system abwarten
Verfasst: Montag 16. Mai 2011, 09:53
von snafu
`sin_cos.gnu` ist kein Argument von `gnuplot`, sondern es ist eine Umleitung, die den Dateiinhalt von `sin_cos.gnu` in den `stdin` vom Prozess `gnuplot` schreibt. Du solltest das dann auch entsprechend in deinem `subprocess`-Aufruf so umsetzen.
Übrigens, du kannst `Popen()` bereits ein Dateiobjekt für die Umleitung eines Datenstroms mitgeben und musst daher nicht den Umweg über `PIPE` gehen.
Re: os.system abwarten
Verfasst: Montag 16. Mai 2011, 12:57
von mzh
@snafu:
Ich habe jetzt nur diese weitere Möglichkeit gefunden, ich versteh leider nicht genau wie du meinst.
Code: Alles auswählen
[mzh] @ ~/programming/subpro $ python
Python 2.6.1 (r261:67515, Feb 11 2010, 15:47:53)
[GCC 4.2.1 (Apple Inc. build 5646)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import subprocess
>>> gnuproc = subprocess.Popen(['gnuplot'], stdin=subprocess.PIPE, shell=False)
>>> gnuinp = open('sin_cos.gnu', 'r')
>>> gnuinp
<open file 'sin_cos.gnu', mode 'r' at 0x406750>
>>> gnuproc.stdin.write(gni.read())
>>>
Re: os.system abwarten
Verfasst: Montag 16. Mai 2011, 13:34
von BlackJack
@mzh: Du kannst bei `Popen()` anstelle von der `PIPE`-Konstante auch eine geöffnete Datei übergeben. Was ist denn daran jetzt schon wieder nicht zu verstehen!?
Re: os.system abwarten
Verfasst: Montag 16. Mai 2011, 13:37
von mzh
achso, also
Code: Alles auswählen
[mzh] @ ~/programming/subpro $ python
Python 2.6.1 (r261:67515, Feb 11 2010, 15:47:53)
[GCC 4.2.1 (Apple Inc. build 5646)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import subprocess
>>> gnuproc = subprocess.Popen(['gnuplot'], stdin=open('gnuinp.gnu', 'r'), shell=False)
>>>
Re: os.system abwarten
Verfasst: Montag 16. Mai 2011, 18:55
von problembär
mzh hat geschrieben:Auf der Shell würde ich das so aufrufen:
So erhalte ich das 'sin_cos.ps' File.
Mit subprocess.Popen würde ich das jetzt so machen:
Code: Alles auswählen
import subprocess
gnup = subprocess.Popen(['gnuplot', 'sin_cos.gnu'], shell=False)
Was snafu meint, ist: Wo ist denn da das "<" aus dem obigen Shell-Befehl?
Was Du da machst ist doch eine Umleitung der Eingabe:
http://tldp.org/LDP/abs/html/io-redirection.html
So, und ob "subprocess" das mitmacht, wenn Du das "<" einfach als Argument mitgibst, weiß ich nicht. Deswegen benutze und empfehle ich bei solchen komplizierten Shell-Kommandos ja eben doch eher "os.system()" und "os.popen()". Hier wäre das einfach:
Re: os.system abwarten
Verfasst: Montag 16. Mai 2011, 19:11
von cofi
Genau dafür sind die `std*` Parameter des `subprocess.Popen`-Aufrufs da. Und selbst wenn man bei Shellbefehlen bleiben will, gibt es immernoch den Shell-Parameter. Es gibt schlichtweg keinen Grund weiterhin die Funktionen des `os` Moduls zu nutzen.
@mzh: Nein. Du solltest die Datei explizit schliessen und dich nicht auf den GC verlassen.
Re: os.system abwarten
Verfasst: Montag 16. Mai 2011, 20:52
von mzh
problembär hat geschrieben:
Wenn das in meinem Fall funktionieren würde, hätte ich mir ja den ganzen Thread sparen können. Das habe ich natürlich schon versucht, das Problem, soweit ich es verstehe, ist in diesem Fall aber, dass der gnuplot Prozess dabei in einer neuen Shell startet. Dh. Python selber setzt die Abarbeitung seines Skriptes fort, obwohl die Ausgabe aus dem Prozess von os.system(...) für die Fortsetzung des Skriptes benötigt wird. Dh. Python sollte "warten", bis der Flow of Control wieder zurück zum Skript kommt.
@cofi: So?
Code: Alles auswählen
[mzh] @ ~/programming/subpro $ python
Python 2.6.1 (r261:67515, Feb 11 2010, 15:47:53)
[GCC 4.2.1 (Apple Inc. build 5646)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import subprocess
>>> inFile = open('gnuinp.gnu', 'r')
>>> gnuproc = subprocess.Popen(['gnuplot'], stdin=inFile.read(), shell=False)
>>> inFile.close()
Hab jetzt nicht getestet, ob da stehen soll 'stdin=inFile.read()', oder bloss 'stdin=inFile'.
Re: os.system abwarten
Verfasst: Montag 16. Mai 2011, 21:54
von snafu
Code: Alles auswählen
with open('sin_cos.gnu') as infile:
subprocess.call('gnuplot', stdin=infile)
Re: os.system abwarten
Verfasst: Montag 16. Mai 2011, 21:56
von cofi
Nein, so wie ich es in meinem Beispiel gezeigt habe, damit der Code da ran kommt musst du das in ein `try ... finally` Konstrukt wickeln.
In dem Code hast du schon wieder keine File-Objekt mehr sondern einen String, also ja ohne `.read()`.
Re: os.system abwarten
Verfasst: Montag 16. Mai 2011, 23:49
von derdon
mzh hat geschrieben:Hab jetzt nicht getestet, ob da stehen soll 'stdin=inFile.read()', oder bloss 'stdin=inFile'.
Und warum nicht?
Re: os.system abwarten
Verfasst: Dienstag 17. Mai 2011, 06:59
von snafu
Es hat beim Helfen immer so einen faden Beigeschmack, wenn man den Eindruck hat, dass der Fragesteller zu keinem Zeitpunkt so wirklich zu wissen scheint, was er da überhaupt gerade tut.

Re: os.system abwarten
Verfasst: Dienstag 17. Mai 2011, 10:07
von mzh
snafu hat geschrieben:Es hat beim Helfen immer so einen faden Beigeschmack, wenn man den Eindruck hat, dass der Fragesteller zu keinem Zeitpunkt so wirklich zu wissen scheint, was er da überhaupt gerade tut.

Es erscheint mir angebracht zu bemerken, dass ich für Hinweise sehr froh und dankbar bin. Auf Kommentare, die mir unterstellen ich versuche der Beschäftigung mit der Materie auszuweichen muss ich nicht eingehen. Ich finde ein Forum eine sehr gute Form sich zu Wissen auszutauschen und ich habe hier schon oft den richtigen Hinweis gefunden, wie ein Problem zu lösen sei.
Re: os.system abwarten
Verfasst: Dienstag 17. Mai 2011, 10:38
von snafu
Ich meinte nicht so sehr, dass du es dir gemütlich machen willst und hoffst, alles vorgekaut zu bekommen. Du probierst ja durchaus Sachen selbst aus. Wenn man sich mal etwas blöde auf neuem Terrain anstellt, ist das ja durchaus entschuldbar. Bei dir hat man aber den Eindruck, dass du Trial-and-Error mäßig so lange herum probierst bis du irgendwann ein funktionierendes Ergebnis hast. Der Anstoß zu meinem Kommentar war der Moment als du das Ergebnis von `.read()` an `stdin` übergeben wolltest. Ist dir bewusst, was die `read()`-Methode eines Dateiobjekts zurück gibt? Wenn ja, dann vergleiche mal den Typen des Rückgabewertes mit dem Typen, welcher von `Popen()` (s. Doku) erwartet wird. Ein solches Vorgehen nenne ich halt "planlos". Nichts für ungut, ich bin ganz zu Anfang teilweise auch so vorgegangen. Ich will dich eigentlich nur ermuntern, wenn Begriffe wie "Dateiobjekt" fallen, dich auch mal damit zu beschäftigen, was ein Dateiobjekt genau ist und wie es in der Praxis verwendet wird. Um alle Informationen über die Teilbereiche eines Anwendungsgebiets durchzugehen, braucht man durchaus auch schon einmal mehr als nur einen Abend an Recherche. So ist das nunmal. Dafür weiß man am Ende aber zumindest relativ gut, was man da tut und warum man es tut.

Re: os.system abwarten
Verfasst: Dienstag 17. Mai 2011, 11:58
von mzh
Das Leben ist bekanntlich kein Ponyhof, da geb ich dir vorbehaltlos Recht.
Re: os.system abwarten
Verfasst: Dienstag 17. Mai 2011, 16:27
von problembär
mzh hat geschrieben:
So erhalte ich das 'sin_cos.ps' File.
mzh hat geschrieben:problembär hat geschrieben:
Wenn das in meinem Fall funktionieren würde, hätte ich mir ja den ganzen Thread sparen können. Das habe ich natürlich schon versucht, das Problem, soweit ich es verstehe, ist in diesem Fall aber, dass der gnuplot Prozess dabei in einer neuen Shell startet. Dh. Python selber setzt die Abarbeitung seines Skriptes fort, obwohl die Ausgabe aus dem Prozess von os.system(...) für die Fortsetzung des Skriptes benötigt wird. Dh. Python sollte "warten", bis der Flow of Control wieder zurück zum Skript kommt.
Ich bastel ja auch ganz gern herum. Also, warum dann nicht:
Code: Alles auswählen
import os
import time
os.system("gnuplot < sin_cos.gnu")
while not os.path.isfile("sin_cos.ps"):
time.sleep(0.2)
? Würde auch gut zum Threadtema passen : "os.system abwarten".
Gruß
P.S.: Wenn Dein Problem wirklich die Subshell ist, kannst Du statt "os.system()" auch mal "os.execl()" und weitere probieren (Infos in "pydoc.os").
Bei der auszuführenden Datei ist dabei offenbar der vollständige Pfad anzugeben.
Beispielsweise geht bei mir folgendes:
Re: os.system abwarten
Verfasst: Dienstag 17. Mai 2011, 17:08
von BlackJack
@problembär: Das wartet nur solange bis die Datei existiert. Ich nehme doch mal an das die Datei auch *vollständig* sein sollte bevor das Programm weiter läuft. Sollte es die Datei schon vorher gegeben haben, wird auch nicht gewartet. Und es verwendet `os.system()`.

Re: os.system abwarten
Verfasst: Dienstag 17. Mai 2011, 18:50
von problembär
BlackJack hat geschrieben:@problembär: Das wartet nur solange bis die Datei existiert. Ich nehme doch mal an das die Datei auch *vollständig* sein sollte bevor das Programm weiter läuft. Sollte es die Datei schon vorher gegeben haben, wird auch nicht gewartet. Und es verwendet `os.system()`.

Natürlich kann man auch noch die Dateigröße prüfen oder z.B. dem Dateinamen einen Zusatz mitgeben, um sie eindeutig als die von dem system-Befehl angelegte zu identifizieren.
Mit etwas Phantasie wäre das doch wohl klar.