我认为在环境稍有修改的情况下运行外部命令是很常见的情况。这就是我倾向于这样做的方式:
import subprocess, os
my_env = os.environ
my_env["PATH"] = "/usr/sbin:/sbin:" + my_env["PATH"]
subprocess.Popen(my_command, env=my_env)
我感觉到有更好的方法了。看起来还好吗?
/usr/sbin
:-) 的路径时是否非常相关
我认为在环境稍有修改的情况下运行外部命令是很常见的情况。这就是我倾向于这样做的方式:
import subprocess, os
my_env = os.environ
my_env["PATH"] = "/usr/sbin:/sbin:" + my_env["PATH"]
subprocess.Popen(my_command, env=my_env)
我感觉到有更好的方法了。看起来还好吗?
/usr/sbin
:-) 的路径时是否非常相关
Answers:
我认为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)
os.environ.copy
的env
变量,但您需要分配调用该方法的结果os.environ.copy()
来env
。
shell=True
在subprocess.Popen
调用中使用时,环境变量解析才真正起作用。请注意,这样做可能会带来安全隐患。
my_command
只是要运行的命令。例如,它可以是/path/to/your/own/program
任何其他“可执行”语句。
这取决于问题所在。如果要克隆和修改环境,一种解决方案可能是:
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标识符,并且也预先知道(在编码时),第二种方法存在问题。如果不是这种情况,您可能应该寻找另一种方法。
dict(mapping, **kwargs)
。我以为是。注意:它os.environ
会按照当前接受的答案中的@Daniel Burke的建议进行复制而不进行修改,但是您的答案更为简洁。在Python 3.5及更高版本中,您甚至可以这样做dict(**{'x': 1}, y=2, **{'z': 3})
。见pep 448。
使用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.pathsep
对于跨平台工作的路径,也更喜欢使用而不是“:”。见stackoverflow.com/questions/1499019/...