题
我认为,运行一个外部命令稍作修改的环境是一个非常常见的情况。这就是我倾向于这样做:
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.environ对象等,我这样做:
process = subprocess.Popen(['env', 'RSYNC_PASSWORD=foobar', 'rsync', \
'rsync://username@foobar.com::'], stdout=subprocess.PIPE)
env参数接受一个字典。你可以简单地采取os.environ,添加一个键(您所需的变量)(在字典的副本,如果你必须)到,并用它作为参数传递给Popen
。
我知道这已经回答说对于一些时间,但有一些点的一些可能想要知道关于使用PYTHONPATH而不是路径,在他们的环境变量。我已经概述了一个解释的运行python脚本cronjobs,处理与修改后的环境中以不同的方式(在这里找到).认为这将是一些良好的那些人,像我一样,需要的只是多一点,这个回答提供。
在某些情况下,你可能希望只传下来的环境变量的子需求,但我想你已经得到了普遍想法是正确的(这就是我如何做到这一点)。