2015-07-20 75 views
1

是否可以創建一個shell對象並在命令執行後操作它而不會丟失它的數據?Python與父shell環境一起工作

from subprocess import * 
sh.Popen('/bin/bash', stdout=PIPE) 
sh.communicate('source /path/to/file/env.sh') 
print os.getenv('ENV_VAR1') 

ENV_VAR1應該採購/path/to/file/env.sh後可用,但事實並非如此。 這部分代碼沒有按預期工作,我怎樣才能使它工作?

這裏是另一個嘗試這是不工作的,以及

os.system('source env.sh; echo $ENV_VAR1') #Prints out correct value 
os.system('echo $ENV_VAR1') #Prints nothing 

回答

0

這不是一個Python的問題。環境變量只對其設置的進程和任何子進程可見。在這些示例中,您正試圖在子級中設置環境變量並從父級訪問它們,但這種做法根本無效。

如果您想要將這些值反饋給父級,您需要安排某種顯式通信(例如,讓孩子將值寫入標準輸出並從父級讀取它們)。

+1

OP不說這是一個問題。看起來他/她需要一種方法來保存後續shell調用之間的上下文 –

3

你可以echo $ENV_VAR1,並使用communicate從標準輸出返回結果:

import subprocess 
proc = subprocess.Popen('source /path/to/file/env.sh; echo $ENV_VAR1', 
         stdout=PIPE, shell=True) 
env_var1, err = proc.communicate() 
print(env_var1) 

另一種選擇可能是使用Miki Tebeka's source function

import subprocess 
import os 

def source(script, update=True): 
    """ 
    source a file and return the environment as a dict. 
    http://pythonwise.blogspot.fr/2010/04/sourcing-shell-script.html (Miki Tebeka) 
    """ 
    proc = subprocess.Popen("source %s; env -0" % script, stdout=subprocess.PIPE, 
          shell=True) 
    output, err = proc.communicate() 
    env = dict((line.split("=", 1) for line in output.split('\x00') if line)) 
    if update: 
     os.environ.update(env) 
    return env 

source('/path/to/env.sh') 
print(os.environ['ENV_VAR1']) 

如果/path/to/file/env.sh包含

ENV_VAR1=FOO 
export ENV_VAR1 

scri PT上面打印

FOO 

以上,I made a small change到 的功能,使得env使用一個空字節(\x00)以分離輸出 線。這使得解析跨越多個 行的名稱/值對成爲可能。

+0

bash的很好的解決方案,但不工作的是源文件是'tcsh'文件,'proc.communicate()'返回空元組 – PYPL

+0

使用點, 。/path/to/env.sh'來源文件是一個bash主題。但我認爲bash和tcsh都可以使用'source/path/to/env.sh'。我已經改變了上面的代碼(在'source'函數中)來解決這個問題。 – unutbu

相關問題