蟒子/ POPEN与经修饰的环境蟒子/ POPEN与经修饰的环境(Python subprocess

2019-05-09 02:02发布

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

import subprocess, os
my_env = os.environ
my_env["PATH"] = "/usr/sbin:/sbin:" + my_env["PATH"]
subprocess.Popen(my_command, env=my_env)

我有一个感觉:有一个更好的办法; 它看起来好吗?

Answer 1:

我认为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)


Answer 2:

那要看是什么问题。 如果是克隆和修改环境有关的一个解决办法是:

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标识符,并且事先已知的(在编码时),第二种方法有问题。 在情况下,是不是你应该寻找的情况下的另一种方法 。



Answer 3:

您可以使用my_env.get("PATH", '')而不是my_env["PATH"]的情况下, PATH某种程度上不是在原来的环境中定义,但比它看起来罚款等。



Answer 4:

使用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}


Answer 5:

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

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


Answer 6:

env参数接受一本字典。 你可以简单地采取os.environ,添加一个键(您所需的变量)(在字典的副本,如果你必须)到,并用它作为参数传递给Popen



Answer 7:

我知道这已经回答了一段时间,但也有一些可能会想知道在他们的环境变量使用PYTHONPATH,而不是路径的一些点。 我提出与cronjobs与以不同的方式(修改后的环境交易运行Python脚本的解释在这里找到 )。 认为这将是一些很好的为那些谁像我一样,需要的只是略高于提供这个答案更多。



Answer 8:

在某些情况下,你可能希望只传下来的环境变量的子需求,但我想你已经得到了普遍想法是正确的(这就是我如何做到这一点)。



文章来源: Python subprocess/Popen with a modified environment