2011-11-12 111 views
1

我有一個XML,它包含有關由我的python腳本設置到shell中的環境變量的信息。這裏是XML的片段:Python,使用Popen時更改當前shell環境變量?

<envVar name='QTDIR'>/homeqt/libs.qt4/qt4.5.1</envVar> 
<envVar name='MAKE'>which make</envVar> 

這段代碼的這一部分告訴我的python腳本設置環境變量QTDIR和MAKE。

我的關注點是如何設置上述變量。我知道,我可以使用os.environ設置環境變量,做這樣的事情:

os.environ['QTDIR'] = "/homeqt/libs.qt4/qt4.5.1" 

但我不能用它來設置我的make變量,我不得不執行命令「這使得 「(獲取make可執行文件的路徑)。我的目標是使用相同的方法/函數來設置每個變量。

所以,我認爲做這樣的事情:

Popen("QTDIR=/homeqt/libs.qt4/qt4.5.1 ; export QTDIR", shell=True, stdout=PIPE, stderr=PIPE) 
Popen("MAKE=which make ; export MAKE", shell=True, stdout=PIPE, stderr=PIPE) 

但如果我這樣做,變量將只針對子集,而不是當前的shell。

所以,我的問題是,有沒有辦法做我想要的?我不想分析XML和做這樣的事情:

(僞)

if QTDIR has normal value 
    os.environ['QTDIR'] = "/homeqt/libs.qt4/qt4.5.1" 
if MAKE has value to be executed 
    p = Popen("which make", shell=True, stdout=PIPE, stderr=PIPE) 
    stdout, stderr = p.communicate() 
    os.environ['MAKE'] = stdout 
+1

你爲什麼不想要? – Amber

+0

我們有非常複雜的bash shell腳本,如果其他人構建我們的產品,則需要大量的shell腳本。我想在XML中儘可能移動大量信息,並使python腳本調用從中提取的作業。我希望python腳本儘可能簡單。這就是爲什麼。那麼,有可能嗎? – peterphonic

+0

@peterphonic所以,你想有一些值得特別處理,但你不願意在任何地方處理它們? – millimoose

回答

3

我會利用XML屬性。

<envVar name="MAKE" type="command">which make</envVar> 
<envVar name="QTDIR" type="string">/homeqt/libs.qt4/qt4.5.1</envVar> 

僞取決於你的XML庫:

if node.attributes['type'] == 'command': 
    value = os.popen(node.firstChild.text).read() 
elif node.attributes['type'] == 'string': 
    value = node.firstChild.text 
os.environ[node.attributes['name']] = value 
+1

好的答案!更好的是,升級到Nick Coghlan一直倡導的'subprocess.check_output()'標準庫方法,因爲它有更好的設計。 –

+0

我只是搞砸了,我同意這是一個更好的解決方案,但可能不是這個。這就需要你對自己解析命令,如check_output發生在一個參數數組,所以你可能要嘗試像check_output(command.split(」「)),這僅僅是個壞消息,不會做正確的幾乎所有情況下都是這樣(如果我引用了字符串,轉義空格或分號,那麼在它們旁邊沒有空格的情況下呢?)最好將它傳遞給shell的語法分析器。 – stefan

+0

只需將'shell = True'傳遞給函數:'check_output(command,shell = True)' –

0

你的表示是含糊:

<envVar name='QTDIR'>/homeqt/libs.qt4/qt4.5.1</envVar> 
<envVar name='MAKE'>which make</envVar> 

你怎麼MAKE=which makeMAKE=`which make`之間做出選擇:

$ a=which make ; echo $a 
make: *** No targets specified and no makefile found. Stop. 

$ a=`which make` ; echo $a 
/usr/bin/make 

$ a='which make' ; echo $a 
which make 

如果xml文件是由機器生成的並且人類不經常查看/編輯此文件,那麼您可以使用詳細的明確表示法,如suggested by @stefan

否則一個更簡潔和簡單的表現形式可以用於:

QTDIR: /homeqt/libs.qt4/qt4.5.1 
$MAKE: which make 

下面是一個Python腳本,解析該格式轉換成字典:

for line in file: 
    name, sep, value = map(str.strip, line.partition(':')) 
    if sep: # ':' is in the line   
     if name.startswith('$'): 
      name = name[1:] # strip '$' 
      value = subprocess.check_output(value, shell=True).strip() 
     d[name] = value 

或者你可以做如:

d = yaml.load(file) # yaml is as complex as xml, but less explicit i.e., worse 
# and transform keys that start with '$' here 

如果您需要更復雜的功能,xml格式可能是合理的回退。

+0

其實區別,我認爲XML是一個更好的解決方案。它不僅包含有關變量的信息,也有執行的作業:。\t \t \t <作業標籤='Create_Directories '> \t \t \t \t cd $ MAINPATH; \t \t \t \t mkdir -p $ TARGET; \t \t \t \t cd「$ MAINPATH/$ TARGET」; \t \t \t \t室射頻$ VARIANT \t \t \t – peterphonic

+0

@peterphonic:在這種情況下,DB,如源碼可能更適合於跟蹤工作狀態。 – jfs