Я считаю, что запуск внешней команды с немного измененной средой является очень распространенным случаем. Вот как я это делаю:
import subprocess, os
my_env = os.environ
my_env["PATH"] = "/usr/sbin:/sbin:" + my_env["PATH"]
subprocess.Popen(my_command, env=my_env)
У меня есть чувство, что есть лучший способ; это выглядит хорошо?
python
subprocess
popen
Oren_H
источник
источник
os.pathsep
вместо «:» пути, которые работают на разных платформах. См. Stackoverflow.com/questions/1499019/…/usr/sbin
:-)Ответы:
Я думаю, что
os.environ.copy()
лучше, если вы не собираетесь изменять os.environ для текущего процесса:источник
os.environ.copy
кenv
переменной , но вы должны присвоить результат вызова методаos.environ.copy()
кenv
.shell=True
в своемsubprocess.Popen
вызове. Обратите внимание, что это может иметь последствия для безопасности.my_command
это просто команда для запуска. Это может быть, например,/path/to/your/own/program
или любой другой «исполняемый» оператор.Это зависит от того, в чем проблема. Если это клонировать и модифицировать среду, одним из решений может быть:
Но это в некоторой степени зависит от того, что замененные переменные являются действительными идентификаторами Python, которыми они чаще всего являются (как часто вы сталкиваетесь с именами переменных среды, которые не являются буквенно-цифровыми + подчеркивания или переменными, начинающимися с цифры?).
В противном случае вы могли бы написать что-то вроде:
В очень странном случае (как часто вы используете управляющие коды или не-ascii символы в именах переменных окружения?), Что ключи окружения
bytes
вы не можете (на python3) даже использовать эту конструкцию.Как вы можете видеть, методы (особенно первые), используемые здесь, выгодно используют ключи среды, как правило, действительные идентификаторы Python, а также известные заранее (во время кодирования), у второго подхода есть проблемы. В случаях, когда это не так, вы, вероятно, должны искать другой подход .
источник
dict(mapping, **kwargs)
. Я думал, что это было или. Примечание: он копируетсяos.environ
без изменения, как предложено @Daniel Burke в принятом в настоящее время ответе, но ваш ответ более лаконичен. В Python 3.5+ вы могли бы даже сделатьdict(**{'x': 1}, y=2, **{'z': 3})
. Смотрите Пеп 448 .вы могли бы использовать
my_env.get("PATH", '')
вместо того, чтобыmy_env["PATH"]
в случае, если что-PATH
то не определено в исходной среде, но в остальном это выглядит нормально.источник
С Python 3.5 вы можете сделать это следующим образом:
Здесь мы получаем копию
os.environ
и переопределенноеPATH
значение.Это стало возможным благодаря PEP 448 (Дополнительные обобщения распаковки).
Другой пример. Если у вас есть среда по умолчанию (т. Е.
os.environ
) И диктовка, с которой вы хотите переопределить значения по умолчанию, вы можете выразить это следующим образом:источник
Чтобы временно установить переменную среды без необходимости копировать объект os.envrion и т. Д., Я делаю это:
источник
Параметр env принимает словарь. Вы можете просто взять os.environ, добавить ключ (желаемую переменную) (к копии dict, если необходимо) и использовать его в качестве параметра для
Popen
.источник
os.environ['SOMEVAR'] = 'SOMEVAL'
Я знаю, что на это уже отвечали, но есть некоторые моменты, которые некоторые могут захотеть узнать об использовании PYTHONPATH вместо PATH в своей переменной среды. Я обрисовал в общих чертах объяснение запуска сценариев Python с помощью cronjobs, которое по-другому работает с измененной средой (см. Здесь ). Подумал, что это будет полезно для тех, кому, как и мне, нужно чуть больше, чем этот ответ.
источник
В определенных обстоятельствах вам может потребоваться передать только те переменные окружения, которые нужны вашему подпроцессу, но я думаю, что вы в целом правильно поняли (я тоже так делаю).
источник