在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
foobar.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的项目。