Seite 1 von 1

Kommando mit ">" ausführen

Verfasst: Mittwoch 9. Dezember 2009, 21:51
von bronkopavel
Mein erster Python "Showstopper":
ich will folgendes ausführen:

Code: Alles auswählen

cmd = "avr-nm -n file.elf > file.sym"

file = open("file.sym", "w")
file.close()

process = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE)
stdout = process.communicate()[0]
print stdout
Leider wird mit dem > Operator auf die Kommandozeile redirektet und nicht in die Datei. file.elf existiert natürlich. Was mache ich falsch?

Re: Kommando mit ">" ausführen

Verfasst: Mittwoch 9. Dezember 2009, 22:08
von cofi
bronkopavel hat geschrieben:Was mache ich falsch?
Du verwechselst Python mit ner Shell?
Das clobbing ist ein Feature der Shells und hat primaer nichts mit dem Prozess zu tun, evtl. geht es, wenn du eine Shell dazwischenschaltest (`shell=True`), aber der saubere Weg ist, das selbst zu uebernehmen.

Dein Command-Handling ist btw recht fahrlaessig.
Ungetestet:

Code: Alles auswählen

cmd = ["avr-nm", "-n", "file.elf"]

with open("file.sym", "w") as fobj:
    process = subprocess.Popen(cmd, stdout=subprocess.PIPE)
    fobj.write(process.communicate()[0])

Verfasst: Mittwoch 9. Dezember 2009, 22:23
von bronkopavel
Danke, es funktioniert!
Dein Command-Handling ist btw recht fahrlaessig.
Ich habe die Zeilen

Code: Alles auswählen

process = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE)
stdout = process.communicate()[0]
print stdout
aus dem Netz und bin Pythonanfänger. Ist das mit split() nicht so gut?Warum?
Das mit "with" kenne ich noch nicht, werde es aber noch nachlesen.
Btw. ich versuche einen maker für den avr-gcc zu schreiben und möchte mittels threading alle compiler aufrufe "parallel" starten. Ich weiß nur, das ich das modul threading verwenden werde, vielleicht kennst du hier ein Beispiel wie ich:
1. mehrere threads starten (compilieren)
2. warten bis alle fertig sind bzw. abfangen wenn Fehler passiert sind
3. linken

Gruß
Bronko

Verfasst: Mittwoch 9. Dezember 2009, 22:38
von fhoech
Einen Einzeiler hätte ich noch :)

Code: Alles auswählen

returncode = subprocess.call(["avr-nm", "-n", "file.elf"], stdout=open("file.sym", "w"))

Verfasst: Donnerstag 10. Dezember 2009, 07:44
von BlackJack
@bronkopavel: Das mit dem `split()` funktioniert zum Beispiel nicht mehr, wenn in einem der Argumente ein Leerzeichen vorkommt.

Wenn Du in Deinem Programm die Ausgaben nicht verarbeitest, kommst Du auch ohne Threads aus, weil die Prozesse ja grundsätzlich auch asynchron gestartet werden.

@fhoech: Da wird die Datei aber nicht mehr explizit geschlossen und wenn man das mit oft macht, können einem die Dateihandles ausgehen, wenn der Garbage Collector nicht hinterherkommt. Und nein, dass das vermutlich bei der aktuellen CPython-Implementierung nicht passieren wird, ist IMHO kein Argument.

Verfasst: Donnerstag 10. Dezember 2009, 08:43
von bronkopavel
Danke für die Antworten, das mit split() hab ich kapiert, werde jetzt wohl eine Liste für die Argumente nehmen. Bei mir ist das gegangen (Zufallsprodukt).

@BlackJack: Du hast recht, dass ich eigentlich keine threads brauche, jedoch weiß ich nicht, wie ich dann weiß, wann alle Compilervoränge beendet sind (damit ich mit dem Linken usw. starten kann). Der Output des Compiler auf der Kommandozeile reicht, ein Abfangen und Weiterverarbeiten ist nicht notwendig. Der Output der Vorgänge sollte aber nicht verschachtelt ausgegeben werden.
Da die Anzahl der (parallelen) Compilervorgänge bekannt ist, könnte ich evtl eine (globale) Variable runterzählen oder geht das auch eleganter mit einer queue (da könnte man poppen :lol:)?
Ziel ist es das das ganze möglich schnell läuft (später werde ich evtl. noch die Anzahl der Prozessoren/Compilervorgänge berücksichtigen)

Verfasst: Freitag 11. Dezember 2009, 03:08
von BlackJack
@bronkopavel: Wenn sich die Ausgabe der parallel gestarteten Prozesse nicht vermischen soll, dann musst Du sie doch selber im Skript sammeln und kontrolliert nacheinander ausgeben. Sonst kann man das nicht garantieren. Also doch Threads. :-)

Threads haben eine `join()`-Methode und bei `subprocess.Popen`-Exemplaren blockiert die `communicate()`-Methode ja so lange bis der Prozess fertig ist.

--set-section-flags=.eeprom="alloc,load" mit subp

Verfasst: Dienstag 5. Januar 2010, 13:04
von bronkopavel
Ich schaffe es einfach nicht den .o.g. string als Teil meines Programmaufrufs mit den Anführungszeichen auszugeben:

Code: Alles auswählen

cmdLine = list()   
cmdLine.append(r'--set-section-flags=.eeprom="alloc,load"')
print cmdLine
print "REAL CMD LINE: ", subprocess.list2cmdline(cmdLine)
Das kommt dabei raus:
['--set-section-flags=.eeprom="alloc,load"']
REAL CMD LINE: --set-section-flags=.eeprom=\"alloc,load\"
Warum ist der String in der Liste plötzlich mit zwei \ ??
[/quote]