Python子stream程/ Popen与修改后的环境

我相信在稍微修改一下的环境下运行一个外部命令是一个很常见的情况。 这就是我倾向于这样做的方式:

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) 

这取决于问题是什么。 如果要克隆和修改环境,解决scheme可能是:

 subprocess.Popen(my_command, env=dict(os.environ, PATH="path")) 

但是,这在一定程度上取决于被replace的variables是有效的Python标识符,这是他们最经常使用的(多久你会遇到非字母数字+下划线的环境variables名称或以数字开头的variables?)。

否则,你可以写一些东西,如:

 subprocess.Popen(my_command, env=dict(os.environ, **{"Not valid python name":"value"})) 

在非常奇怪的情况下(你在环境variables名称中使用控制代码或非ASCII字符的频率是多less?)环境的键是你不能(在python3上)的bytes ,甚至使用该构造。

正如你所看到的,这里使用的技术(特别是第一种)通常是有效的Python标识符,并且也是事先已知的(在编码时),第二种方法有问题。 在情况不是这样的情况下,你应该寻找另一种方法 。

如果PATH以某种方式未在原始环境中定义,则可能使用my_env.get("PATH", '')而不是my_env["PATH"] ,但my_env["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} 

我知道这已经回答了一段时间了,但是有些人可能想知道在他们的环境variables中使用PYTHONPATH而不是PATH。 我已经概述了使用cronjobs以不同方式处理修改过的环境( 在这里find )来运行python脚本的解释。 认为对于像我这样的人来说,只需要比提供的答案多一点就好了。

要临时设置一个环境variables,而不必复制os.envrion对象等,我这样做:

 process = subprocess.Popen(['env', 'RSYNC_PASSWORD=foobar', 'rsync', \ 'rsync://username@foobar.com::'], stdout=subprocess.PIPE) 

在某些情况下,你可能只想传递你的subprocess需要的环境variables,但是我认为你总体上有正确的想法(这也是我的做法)。

env参数接受一个字典。 你可以简单地采取os.environ,添加一个关键字(你想要的variables)(如果你必须的字典的副本),并将其用作Popen的参数。

我正在使用玛雅软件内的subprocess,它有它自己的解释器。 通过改变玛雅内的Pythonpath,我可以用我select的Python安装和库启动它。

 import os import subprocess os.environmnet["PYTHONPATH"] = "C:/Python27" command = "C:/Python27/python.exe d:/mypyfile.py args" subprocess.Popen(command) 

一旦我完成在这个环境中启动,我可以通过重新设置“PYTHONPATH”来重新转换到Maya解释器