2013-05-14 29 views
5

我有哪裏某些參數被設置像一個shell腳本:
k.sh:在Python腳本中使用shell變量不工作

export var="value" 
export val2="value2" 

然後,我有我在哪裏調用一個python腳本shell腳本,並想用這些enviornment變量
ex1.py:

import subprocess 
import os 
subprocess.call("source k.sh",shell=True) 
print os.environ["var"] 

但我得到KeyError
我如何在我的Python腳本中使用這些shell變量?

+0

它可以與'os.system'而不是'subprocess.call'一起使用嗎? – SethMMorton 2013-05-14 18:25:25

+0

@SethMMorton:不,它不適用於os.system – ftw 2013-05-14 18:29:43

+0

這不是一個好主意。問題是你爲什麼要這樣做。你真的想在這裏做什麼?只需將變量傳回父級? – cmd 2013-05-14 18:44:41

回答

1

subprocess.call在一個新進程中啓動shell,該進程調用source。無法從子進程修改流程中的環境。

+0

這並不完全有幫助。我敢打賭你可以得到子進程的環境。 – Marcin 2013-05-14 18:22:00

+0

@Marcin它要麼需要子進程的幫助(例如,通過打印環境並從父進程讀回),還是需要更多的參與。遠不是微不足道的,它肯定*不會在父級中通過'os.environ'工作。 – robertklep 2013-05-14 18:28:41

0

正如chepner指出的那樣。您的子流程部分單獨運行。 與環境變量的使用必須要以啓動python腳本之前做..

例如:

C:\Users\anton\Desktop\githubs>echo %x% 
y 

C:\Users\anton\Desktop\githubs>python 
Python 2.7.3 (default, Apr 10 2012, 23:31:26) [MSC v.1500 32 bit (Intel)] on win32 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import os 
>>> os.environ['x'] 
'y' 
>>> 

採購之前,啓動腳本但是將穿越了你的環境變量,或者如果您執行多個給子進程調用的命令在你獲得它之後也會很棒。例如:

import subprocess 
import os 
x = subprocess.call("source k.sh",shell=True, STDIN=subprocess.PIPE, STDOUT=subprocess.PIPE) 
y = subprocess.call("echo $var",shell=True, STDIN=x.stdout, STDOUT=subprocess.PIPE) 

從未嘗試過,如前所述。在發佈之前將其來源。

2

您可以使用k.sh運行Python單行程序將os.environ的內容打印爲JSON。然後使用json.loads到輸出轉換回字典中的主要過程:

import subprocess 
import os 
import json 
PIPE = subprocess.PIPE 
output = subprocess.check_output(
    ". ~/tmp/k.sh && python -c 'import os, json; print(json.dumps(dict(os.environ)))'", 
    shell=True) 
env = json.loads(output) 
print(env["var"]) 

產生

value 
1

如果你想設置的環境,然後運行一個Python腳本,以及,設置環境並運行使用亞軍的Python腳本:

亞軍

#! /bin/bash 
. k.sh 
exec ex1.py 

就是這樣。

ex1.py

#import subprocess 
import os 
#subprocess.call("source k.sh",shell=True) 
print os.environ["var"] 
0

/U/unutbu已經回答了這個問題。不過我固定的情侶蟲子在他的代碼:

def run_external_script(script): 
    if is_windows(): 
     command = script+" && python -c \"import os; print dict(os.environ)\"" 
    else: 
     command = ". "+ script+" && python -c 'import os; print dict(os.environ)'" 

    output = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True).communicate()[0] 
    r = re.compile('{.*}') 
    m = r.search(output) 
    try: 
     env = eval(m.group(0)) 
    except: 
     error("Something went wrong in " + script) 
     error(output) 
    return env 

還有幾個小區別:

  • 此代碼的工作既Windows/Linux上
  • 我換成subprocess.check_output與subprocess.call ,check_output需要Python 2.7
  • 當我運行他的代碼時,std out腳本也會打印在輸出變量中。因此,我使用re來獲取字典中兩個{}之間的所有內容,例如{'var1'= 1,'var2'='x'}。
  • 而不是使用json,我用python的eval。有注射的機會,所以使用它需要您自擔風險。如{; exit(1); }