我认为,运行一个外部命令稍作修改的环境是一个非常常见的情况。这就是我倾向于这样做:

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,处理与修改后的环境中以不同的方式(在这里找到).认为这将是一些良好的那些人,像我一样,需要的只是多一点,这个回答提供。

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top