shellscript von python aufrufen (umgebungsvariablen setzen)

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
edwood
User
Beiträge: 8
Registriert: Montag 9. März 2009, 11:55

hi, ich möchte ein shell-script über python aufrufen das bestimmte umgebungsvariablen setzt, problem ist nur, dass wenn ich das über subprocess oder os.system aufrufe die umgebungsvariablen nicht in der umgebung von dem python script gesetzt werden sondern nur in der vom erzeugten prozess

im moment schauts so aus, ganz simple:

Code: Alles auswählen

script = "./env.sh"         # das script soll die umgebungsvariablen setzen
subprocess.call(script, shell=True)
# hier sollen die umgebungsvariablen noch da sein
das shell-script kann ich dabei aber nicht ändern!
und nachdem sich das shell script auch des öfteren ändern kann (unabhängig von mir), kann ich jetzt auch nicht einfach die variablen in das python script hardcoden
ms4py
User
Beiträge: 1178
Registriert: Montag 19. Januar 2009, 09:37

Warum setzt du die Variablen nicht direkt im PythonSkript?

Code: Alles auswählen

os.environ["PATH"] += ";/usr/bin/python" 
Ansonsten beschreib mal genauer, was du überhaupt bezwecken willst!
BlackJack

@edwood: Das was Du willst geht nicht. Prozesse können nicht die Umgebungsvariablen ihrer Elternprozesse verändern.
edwood
User
Beiträge: 8
Registriert: Montag 9. März 2009, 11:55

ice2k3 hat geschrieben:Warum setzt du die Variablen nicht direkt im PythonSkript?
um mich mal selbst zu quoten:
und nachdem sich das shell script auch des öfteren ändern kann (unabhängig von mir), kann ich jetzt auch nicht einfach die variablen in das python script hardcoden
heißt soviel wie, dass ich keine kontrolle über das shell script habe, d.h. andere benutzer ändern das indem sie darin neue variablen setzen, alte löschen usw. In meinem python script bekomme ich diese shell script nur als input und muss es ausführen. Die Umgebungsvariablen die da aber gesetzt werden brauch ich für das komplette restliche Programm

@BlackJack: ok, das habe ich vermutet, gibts da ein gebräuchliches work-around? dachte da an sowas wie die komplette environment im subprocess ausgeben und das dem elternprozess (sprich python-script) übergeben und dort mit dem environment des elternprozesses vergleichen und die entsprechende unterschiede in python zu setzen. scheint nur etwas viel aufwand für so ein problem zu sein.
lunar

Die Alternative wäre, dass Shell-Skript zu parsen. Mit "shlex" gibt es ein rudimentäres Modul dafür in der Standardbibliothek.
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

@edwood:
Läuft Dein Script im daemon-Modus, oder warum mußt Du die Umgebungsvariablen zur Laufzeit ändern?

Ansonsten könnte man ja einfach das Pythonscript in env.sh aufrufen und so mit den geänderten Variablen arbeiten.
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Eine weniger aufwändige (argh) Alternative zum Parsen eines Shellskripts (wo alle möglichen Befehle stehen können) ist es, das Skript von der Shell ausführen zu lassen, und in derselben Shell das neue Environment auszugeben.

Da fallen mir spontan zwei Möglichkeiten ein (env.sh enthält bei mir FOO=bar; "Popen" und "PIPE" kommen aus [mod]subprocess[/mod]):

1. wenn das Skript "export" verwendet (was es sollte), /proc:

Code: Alles auswählen

>>> Popen("sh -c '. ./env.sh; cat /proc/self/environ'", shell=True, env={}, stdout=PIPE).communicate()[0].split('\x00')[:-1]
['FOO=bar', 'PWD=/tmp']
2. "set", leider hat es da ein paar mehr shell-interne Variablen:

Code: Alles auswählen

>>> Popen("sh -c '. ./env.sh; set'", shell=True, env={}, stdout=PIPE).communicate()[0].splitlines()
["FOO='bar'", "IFS=' \t", "'", "OPTIND='1'", "PATH='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'", "PPID='31286'", "PS1='$ '", "PS2='> '", "PS4='+ '", "PWD='/tmp'"]
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
edwood
User
Beiträge: 8
Registriert: Montag 9. März 2009, 11:55

birkenfeld hat geschrieben: 1. wenn das Skript "export" verwendet (was es sollte), /proc:

Code: Alles auswählen

>>> Popen("sh -c '. ./env.sh; cat /proc/self/environ'", shell=True, env={}, stdout=PIPE).communicate()[0].split('\x00')[:-1]
['FOO=bar', 'PWD=/tmp']
ausgezeichnet, danke, funktioniert ganz gut, von sowas hab ich eh auch oben gesprochen.
Das mit dem parsen hab ich mir auch schon überlegt, würde aber auch nur bedingt funktionieren da ja auch nur unter bestimmten umständen variablen gesetzt werden könnten, z.b. in einer IF-Anweisung oder ähnlichem.
Antworten