Anfängerfrage

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
uwerothfeld
User
Beiträge: 17
Registriert: Freitag 24. Juni 2011, 14:18

Hallo zusammen,

ich versuche gerade mein erstes Py-Skript zu erstellen. Warum geht:

Code: Alles auswählen

def extractAttributes():
    simPath="~/source/simulations"
    simResultPath=simPath+"/results"
    source = "source ~/omnet-setup.export"
    scaveCommand = "scavetool"
    scaveOptionListUniqueStatNames="l -n " 
    scave = source + " && " + scaveCommand + " " + scaveOptionListUniqueStatNames +" "+ simResultPath +"/Sim-0.vec"
    proc = subprocess.Popen([scave], shell=True, stdout=subprocess.PIPE)
aber nicht:

Code: Alles auswählen

...
    proc = subprocess.Popen([scave], stdout=subprocess.PIPE)
...
????
Der Fehler ist:

Code: Alles auswählen

Traceback (most recent call last):
  File "simulations/prepareAndExtractStatsData.py", line 35, in ?
    main()
  File "simulations/prepareAndExtractStatsData.py", line 22, in main
    extractAttributes()
  File "simulations/prepareAndExtractStatsData.py", line 31, in extractAttributes
    (pIn, pOut) = subprocess.Popen([scave], stdout=subprocess.PIPE,stderr=subprocess.PIPE).communicate()
  File "/usr/lib64/python2.4/subprocess.py", line 550, in __init__
    errread, errwrite)
  File "/usr/lib64/python2.4/subprocess.py", line 996, in _execute_child
    raise child_exception
OSError: [Errno 2] No such file or directory

Danke.
Gruß
Zuletzt geändert von uwerothfeld am Freitag 24. Juni 2011, 14:58, insgesamt 1-mal geändert.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Ad 1) Schau dir mal an, was `shell=True` macht und dann suchst du mal im Forum nach subprocess. Dein Aufruf kann aber ohne `shell=True` nicht funktionieren, weil du da lauter Shell-Befehle nutzt, z.b. `source` und `&&`.

Ad 2) Weil `communicate` ein Paar von `stdout, stderr` zurueckgibt, nicht von `stdin, stdout`. Ersteres macht auch keinen Sinn, weil die Eingabe ja `communicate` uebergeben wird.
Newcomer
User
Beiträge: 131
Registriert: Sonntag 15. Mai 2011, 20:41

Hey Cofi, ist dein Bild nicht eine "Lebensform" aus Conways game of live??
uwerothfeld
User
Beiträge: 17
Registriert: Freitag 24. Juni 2011, 14:18

Hey cofi,

also erst einmal dank. Die Ausgaben bekomme ich nun zurück. Dennoch verstehe ich nicht, warum shell=FALSE nicht geht. Ok, statt direkt an die Shell das Kommando weiter zureichen wie bei Shell=True, wird es an os.exec weitergeben, welches einen vernünftigen Path verlangt. Wie kann ich dann die Path-Variable manipulieren? Da scheint mir ja das Problem zu liegen. Oder geht es nicht?

Gruß, uwe
Benutzeravatar
snafu
User
Beiträge: 6895
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Nee, da stecken auch noch ein paar andere Dinge drin, die nur von einer Shell interpretiert werden können, wie cofi ja auch bereits gesagt hat.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

@uwerothfeld: Nein, keine Chance. Es wird nach dem Programm `source ~/omnet... && ...` gesucht, am Pfad zu rütteln bringt hier nichts.

Den `source`-Aufruf solltest du duch ein geeignetes Dictionary loswerden, dass du dann im `Popen`-Aufruf als `env` uebergibst.
Dann musst du noch den langen String aufteilen: Ohne Shell benötigst du eine Liste von Argumenten, also üblicherweise da, wo du jetzt ein Leerzeichen hast.

@Newcomer: Nicht das ich wüsste, es ist aber an den Glider aus Life angelehnt. Das ist aber arg Offtopic ;)
Benutzeravatar
snafu
User
Beiträge: 6895
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Ich würde mir die Mühe gar nicht erst machen und einfach `shell=True` stehen lassen. Wenn man gewisse Shell-Funktionalität nunmal benötigt, dann kann man IMHO auch ruhig eine Shell aufrufen, anstatt das selbst zu implementieren. Solange keine Eingaben von "außen" kommen, ist dieses Vorgehen auch recht sicher. Anstatt der Leerzeichen würde ich aber wahrscheinlich eine Liste nehmen und diese ggf mittels `' '.join(args)` übergeben, falls sie bei `shell=True` nicht richtig interpretiert wird.
uwerothfeld
User
Beiträge: 17
Registriert: Freitag 24. Juni 2011, 14:18

alles klar. vielen Dank für Eure Hilfe :)
Antworten