如何在Python中控制流程环境变量?

时间:2013-06-25 19:43:49

标签: python

我正在尝试更改Python执行过程的环境。似乎正确的方法应该是与os.environ进行交互。但是,我的以下断言失败了:

import os, subprocess
os.environ['ATESTVARIABLE'] = 'value'
value = subprocess.check_output(['echo', '$ATESTVARIABLE'], shell=True)
assert 'value' in value

我应该做些什么来改变当前的环境?上面的代码揭示了我对Python的理解中的哪些缺陷:)?

(请注意,在当前的Python解释器中,os.environ['ATESTVARIABLE']包含期望值。我正在设置运行一些需要特定环境变量的代码,并且可能启动外部进程。显然,如果我想要控制特定子进程的环境,我使用env关键字。)

2 个答案:

答案 0 :(得分:3)

查看subprocess模块的源代码,这是因为使用shell=True的参数列表将相当于......

/bin/sh -c 'echo' '$ATESTVARIABLE'

......当你想要的是......

/bin/sh -c 'echo $ATESTVARIABLE'

以下为我工作......

import os, subprocess

os.environ['ATESTVARIABLE'] = 'value'
value = subprocess.check_output('echo $ATESTVARIABLE', shell=True)
assert 'value' in value

<强>更新

FWIW,两者的区别在于第一种形式......

/bin/sh -c 'echo' '$ATESTVARIABLE'

...只会在没有参数的情况下调用shell的内置echo,并将$0设置为文字字符串'$ATESTVARIABLE',例如......

$ /bin/sh -c 'echo $0'
/bin/sh
$ /bin/sh -c 'echo $0' '$ATESTVARIABLE'
$ATESTVARIABLE

......而第二种形式......

/bin/sh -c 'echo $ATESTVARIABLE'

...将使用单个参数调用shell的内置echo,该参数等于环境变量ATESTVARIABLE的值。

答案 1 :(得分:3)

实际上,以下代码出了什么问题:

import os, subprocess
os.environ['ATESTVARIABLE'] = 'value'
value = subprocess.check_output(['echo', '$ATESTVARIABLE'], shell=True)
assert 'value' in value

是你没有彻底阅读 help page of subprocess

  

在Unix上,shell = True,shell默认为/ bin / sh。如果args是一个字符串,则该字符串指定要通过shell执行的命令。这意味着字符串的格式必须与在shell提示符下键入时完全相同。这包括,例如,引用或反斜杠转义带有空格的文件名。 如果args是序列,则第一项指定命令字符串,任何其他项将被视为shell本身的附加参数。也就是说,Popen相当于:

Popen(['/bin/sh', '-c', args[0], args[1], ...])

这意味着如果您使用数组作为第一个参数调用subprocess.check_out(),则无法获得预期结果。您将使用以下代码重试:

import os, subprocess
os.environ['ATESTVARIABLE'] = 'value'
value = subprocess.check_output('echo $ATESTVARIABLE', shell=True)
assert 'value' in value

它应该按预期工作!

否则,您对环境变量的理解是正确的。修改环境时,会将该环境提供给当前进程的每个分叉子级。