2013-07-12 25 views
3

在Windows上,我想在我的python腳本中使用一個3 rd派對命令行工具。假設它是位於C:\Program Files (x86)\foobar下的foobar.exe。 Foobar附帶一個額外的批處理文件init_env.bat,它將設置要運行的foobar.exe的shell環境。如何從Python執行批處理文件,以便它可以改變調用進程的環境?

我想寫一個python腳本,它將首先調用init_env.bat一次,然後foobar.exe多次。但是,我所知道的所有機制(subprocessos.system和反引號)似乎都爲每次執行產生了一個新進程。因此,調用init_env.bat是無用的,因爲它不會更改python腳本運行的進程的環境,因此每次後續調用foobar.exe都會失敗,因爲它的環境未設置。

是否有可能從python中調用init_env.bat以允許init_env.bat更改調用腳本過程的環境?

回答

0

你試過os.putenv(),然後啓動與os.system()?

http://docs.python.org/2/library/os.html?highlight=os#os

os.putenv(VARNAME,值) 設置名爲varname的字串值的環境變量。對環境的這種更改會影響以os.system(),popen()或fork()和execv()開頭的子進程。

可用性:最受歡迎的Unix,Windows。

注意在某些平臺上,包括FreeBSD和Mac OS X,設置environ可能導致內存泄漏。請參閱putenv的系統文檔。 當支持putenv()時,os.environ中的項目分配會自動轉換爲相應的對putenv()的調用;但是,對putenv()的調用不會更新os.environ,因此實際上最好將其分配給os.environ的項目。

+0

那會做他想做的事嗎?如果我沒有弄錯,他希望等同於* nix'source'命令,在這種情況下,它使用當前環境,以便在腳本執行後持久更改環境變量(而不是創建基於新環境的在當前版本上,然後在腳本執行結束時恢復當前版本)。 – JAB

+0

我認爲這個問題是他在啓動過程之前嘗試設置一些配置,並且完成後並不在乎環境是什麼。 –

3

是否可以調用從蟒蛇init_env.bat的方式,允許 init_env.bat改變調用腳本 進程的環境?

不容易,但是,如果init_env.bat是非常簡單的,你可以嘗試分析它,並進行修改os.environ自己。

否則,在子shell中產生它會更容易,然後調用set來輸出新的環境變量,並從中解析輸出。

我下面的作品...

init_env.bat

@echo off 
set FOO=foo 
set BAR=bar 

foobar.bat

@echo off 
echo FOO=%FOO% 
echo BAR=%BAR% 

爲主。PY

import sys, os, subprocess 


INIT_ENV_BAT = 'init_env.bat' 
FOOBAR_EXE = 'foobar.bat' 


def init_env(): 
    vars = subprocess.check_output([INIT_ENV_BAT, '&&', 'set'], shell=True) 
    for var in vars.splitlines(): 
     k, _, v = map(str.strip, var.strip().partition('=')) 
     if k.startswith('?'): 
      continue 
     os.environ[k] = v 


def main(): 
    init_env() 
    subprocess.check_call(FOOBAR_EXE, shell=True) 
    subprocess.check_call(FOOBAR_EXE, shell=True) 


if __name__ == '__main__': 
    main() 

...爲其python main.py輸出...

FOO=foo 
BAR=bar 
FOO=foo 
BAR=bar 

請注意,我只在地方您foobar.exe的使用批處理文件,因爲我沒有一個.exe文件方便可以確認環境變量的設置。

如果您使用的是.exe文件,則可以從行subprocess.check_call(FOOBAR_EXE, shell=True)中刪除shell=True子句。

+0

除非需要,否則不應傳遞'shell = True'。這裏不需要。 –

+0

@PiotrDobrogost經過測試,它看起來無論如何都不重要。當執行批處理文件時,即使沒有'shell = True',它也會產生一個shell。 'subprocess.check_call(['foo.bat','>','foo.bat'])'仍然會破壞'foo.bat',所以最好把它明確一些,所以很明顯我們需要請注意參數。 – Aya

+0

真棒的主意!謝謝。對於Python 3的支持,我需要添加'var = var.decode('cp1252')' – jhasse

相關問題