2013-06-25 26 views
4

我試圖改變我的Python執行過程的環境。看來正確的做法應該是與os.environ進行交互。然而,我以下斷言失敗:如何在Python中控制進程環境變量?

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關鍵字)。

+0

你的代碼是無效的Python代碼,對不起。請修復它,如果你期望幫助... – Paul

+0

@ paul-我的代碼執行使用Linux和Python 2.7.3(除了意料之外的AssertionError)。你使用的是什麼版本的Python? – dbn

+0

啊。我明白了,您的意思是check_output中的(現在已更正)錯字。謝謝。 – dbn

回答

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的值的參數。

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與殼牌= TRUE,則殼默認爲/ bin/sh的。如果args是一個字符串,則該字符串指定通過shell執行的命令。這意味着該字符串的格式必須與在shell提示符下鍵入時的格式完全相同。這包括,例如,在其中包含空格的引號或反斜線轉義文件名。 如果args是一個序列,則第一項指定命令字符串,而任何其他項目將被視爲殼本身的附加參數。也就是說,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 

它應該按照您的期望工作!

否則,你對環境變量的理解是正確的。當您修改環境時,該環境會分配給當前流程的每個分叉子。

相關問題