Python: экспорт переменных среды в subprocess.Popen(..)

У меня возникла проблема с настройкой переменной среды при вызове subprocess.Popen. Кажется, что переменная среды не устанавливается. Любые предложения о том, как правильно установить переменные среды для вызова командной строки Python?

Моя цель - запустить script, который использует переменную среды, определенную из моего кода Python:

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

но script реагирует так, как будто переменная никогда не была установлена ​​

Вот моя попытка протестировать, используя интерактивный интерпретатор Python:

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

а выход:

"$TEST_VARIABLE"
0

Я думал, что env=d должен установить среду для подпроцесса, но, по-видимому, этого не делает. Любые предложения по устранению этой проблемы?

Ответ 1

Подстановка переменных среды в командной строке выполняется оболочкой, а не /bin/echo. Поэтому вам нужно запустить команду в оболочке, чтобы получить подстановку:

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

Это не означает, что переменная окружения не устанавливается, если shell=False. Даже без shell=True исполняемый файл видит переменные среды, заданные параметром env. Например, date зависит от переменной среды TZ:

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

Вы должны использовать os.environ.copy(), чтобы он работал. Он создает копию всего словаря среды, которую вы затем можете изменить, прежде чем передавать его на подпроцесс, без изменения текущей среды процесса.

Пожалуйста, посмотрите [здесь]: 1

Ответ 3

Для Python 3.5 и более поздних версий вы можете использовать распаковку обобщений, например:

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