2014-10-30 9 views
16

Mam problem z ustawianiem zmiennej środowiskowej w wywołaniu na subprocess.Popen. Wydaje się, że zmienna środowiskowa nie jest ustawiana. Wszelkie sugestie, jak poprawnie ustawić zmienne środowiskowe dla wywołania komendy w Pythonie?Python: Eksportowanie zmiennych środowiskowych w podprocesie.Popen (..)

Moim celem jest, aby uruchomić skrypt, który używa zmiennej środowiskowej ustalonej z mojego kodu Pythona:

d = dict(os.environ) 
d["TEST_VARIABLE"] = str(1234) 
subprocess.Popen('/usr/bin/mybinary', env=d).wait() 

ale skrypt reaguje tak, jakby zmienna nie została ustawiona

Oto moja próba badanie przy użyciu Pythona interaktywny interpreter:

d = dict(os.environ) 
d["TEST_VARIABLE"] = str(1234) 
subprocess.Popen(['/bin/echo', '$TEST_VARIABLE'], env=d).wait() 

i wyjście to:

"$TEST_VARIABLE" 
0 

Myślałem, że env=d powinien ustawić środowisko dla podprocesu, ale najwyraźniej tak nie jest. Wszelkie sugestie dotyczące rozwiązania tego problemu?

Odpowiedz

23

Zamiana zmiennych środowiskowych w linii poleceń jest wykonywana przez powłokę, a nie przez/bin/echo. Więc trzeba uruchomić polecenie w powłoce, aby uzyskać podstawienie:

In [22]: subprocess.Popen('/bin/echo $TEST_VARIABLE', shell=True, env=d).wait() 
1234 
Out[22]: 0 

To nie znaczy, że zmienna nie jest ustawiona, gdy shell=False jednak. Nawet bez shell=True, plik wykonywalny nie widzi zmiennych środowiskowych ustawionych przez parametr env. Na przykład, date zależy od zmiennej TZ środowiska:

In [23]: subprocess.Popen(["date"], env={'TZ': 'America/New_York'}).wait() 
Wed Oct 29 22:05:52 EDT 2014 
Out[23]: 0 

In [24]: subprocess.Popen(["date"], env={'TZ': 'Asia/Taipei'}).wait() 
Thu Oct 30 10:06:05 CST 2014 
Out[24]: 0 
2

Powinieneś użyć os.environ.copy(), aby to działało. Tworzy kopię całego słownika środowiska, który można następnie zmodyfikować przed przekazaniem go do podprocesu, bez modyfikowania bieżącego środowiska procesowego.

Proszę spojrzeć [tutaj]: 1

+1

Problemem nie jest środowisko, ale zastąpienie, jak wyjaśniono przez zaakceptowaną odpowiedź. –

+0

Prawda, ale tytuł postów stwierdza "Eksportowanie", więc jest to przydatne. – gerardw

2

dla Pythona 3.5 i nowsze, można użyć unpacking generalizations, np

env = { 
    **os.environ, 
    "TEST_VARIABLE": str(1234), 
} 
subprocess.Popen('/usr/bin/mybinary', env=env).wait()