我相信,在运行一个外部命令略加修改的环境是一个很常见的情况。 这就是我倾向于这样做:
import subprocess, os
my_env = os.environ
my_env["PATH"] = "/usr/sbin:/sbin:" + my_env["PATH"]
subprocess.Popen(my_command, env=my_env)
我有一个感觉:有一个更好的办法; 它看起来好吗?
我相信,在运行一个外部命令略加修改的环境是一个很常见的情况。 这就是我倾向于这样做:
import subprocess, os
my_env = os.environ
my_env["PATH"] = "/usr/sbin:/sbin:" + my_env["PATH"]
subprocess.Popen(my_command, env=my_env)
我有一个感觉:有一个更好的办法; 它看起来好吗?
我认为os.environ.copy()
是,如果你不打算修改os.environ当前进程更好:
import subprocess, os
my_env = os.environ.copy()
my_env["PATH"] = "/usr/sbin:/sbin:" + my_env["PATH"]
subprocess.Popen(my_command, env=my_env)
那要看是什么问题。 如果是克隆和修改环境有关的一个解决办法是:
subprocess.Popen(my_command, env=dict(os.environ, PATH="path"))
但是,这一定程度上取决于被替代变量是有效的Python标识符,其中他们最经常是(你是否经常遇到未字母+下划线或变量以数字开头的环境变量的名字呢?)。
否则,你就可以向下面这样:
subprocess.Popen(my_command, env=dict(os.environ,
**{"Not valid python name":"value"}))
在非常奇怪的情况(你经常使用环境变量名的控制代码或非ASCII字符?),环境的关键是bytes
,你不能(在python3)甚至可以使用该结构。
正如你所看到的技术(特别是第一),这里使用的好处对环境的键通常是有效的Python标识符,并且事先已知的(在编码时),第二种方法有问题。 在情况下,是不是你应该寻找的情况下的另一种方法 。
您可以使用my_env.get("PATH", '')
而不是my_env["PATH"]
的情况下, PATH
某种程度上不是在原来的环境中定义,但比它看起来罚款等。
使用Python 3.5,你可以这样来做:
import os
import subprocess
my_env = {**os.environ, 'PATH': '/usr/sbin:/sbin:' + os.environ['PATH']}
subprocess.Popen(my_command, env=my_env)
在这里,我们最终得到的副本os.environ
和覆盖PATH
值。
它是由成为可能PEP 448 (附加开箱推广)。
另一个例子。 如果你有一个默认的环境(即os.environ
),并要覆盖使用默认值的字典,你可以表达它是这样的:
my_env = {**os.environ, **dict_with_env_variables}
要临时设置环境变量,而不必复制os.envrion对象等等,我这样做:
process = subprocess.Popen(['env', 'RSYNC_PASSWORD=foobar', 'rsync', \
'rsync://username@foobar.com::'], stdout=subprocess.PIPE)
env参数接受一本字典。 你可以简单地采取os.environ,添加一个键(您所需的变量)(在字典的副本,如果你必须)到,并用它作为参数传递给Popen
。
我知道这已经回答了一段时间,但也有一些可能会想知道在他们的环境变量使用PYTHONPATH,而不是路径的一些点。 我提出与cronjobs与以不同的方式(修改后的环境交易运行Python脚本的解释在这里找到 )。 认为这将是一些很好的为那些谁像我一样,需要的只是略高于提供这个答案更多。
在某些情况下,你可能希望只传下来的环境变量的子需求,但我想你已经得到了普遍想法是正确的(这就是我如何做到这一点)。