如何从Python执行batch file,以便它可以改变调用过程的环境?

Windows上,我想在我的Python脚本中使用第三方命令行工具。 假设它是位于C:\Program Files (x86)\foobar下的foobar.exe 。 Foobar附带一个额外的batch fileinit_env.bat ,它将设置foobar.exe运行的shell环境。

我想写一个python脚本,它将首先调用init_env.bat一次,然后foobar.exe多次。 然而,我所知道的所有机制( 子 进程 , os.system和反引号)似乎都为每个执行产生了一个新的进程。 因此,调用init_env.bat是无用的,因为它不会改变python脚本运行的进程的环境,因此每次后续调用foobar.exe失败,因为它的环境没有设置。

有没有可能从Python调用init_env.bat的方式,允许init_env.bat改变调用脚本进程的环境?

有没有可能从Python调用init_env.bat的方式,允许init_env.bat改变调用脚本进程的环境?

不容易,但是,如果init_env.bat真的很简单,你可以尝试解析它,并自己对os.environ进行更改。

否则,在子shell中产生它就容易多了,然后调用set来输出新的环境变量,然后解析输出。

以下为我工作…

init_env.bat

 @echo off set FOO=foo set BAR=bar 

foob​​ar.bat

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

main.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文件,则可以从lines subprocess.check_call(FOOBAR_EXE, shell=True)删除shell=True子句。

你有没有尝试os.putenv(),然后启动与os.system()?

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

os.putenv(varname,value)将名为varname的环境变量设置为字符串值。 这样的环境变化会影响以os.system(),popen()或fork()和execv()开始的子进程。

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

注意在某些平台上,包括FreeBSD和Mac OS X,设置environ可能导致内存泄漏。 请参阅putenv的系统文档。 当支持putenv()时,os.environ中的项目分配会自动转换为相应的调用putenv(); 然而,对putenv()的调用不会更新os.environ,因此实际上最好将其分配给os.environ的项目。