如何从Python执行批处理文件,以便它能够改变调用进程的环境?
在Windows上,我想在python脚本中使用第三方命令行工具。假设它是如何从Python执行批处理文件,以便它能够改变调用进程的环境?,python,windows,shell,Python,Windows,Shell,在Windows上,我想在python脚本中使用第三方命令行工具。假设它是foobar.exe位于C:\ProgramFiles(x86)\foobar下。Foobar附带了一个额外的批处理文件init_env.bat,该文件将为运行Foobar.exe设置shell环境 我想编写一个python脚本,它将首先调用init_env.bat一次,然后调用foobar.exe多次。然而,我所知道的所有机制(、和backticks)似乎都会为每次执行生成一个新的进程。因此,调用init_env.bat
foobar.exe
位于C:\ProgramFiles(x86)\foobar
下。Foobar附带了一个额外的批处理文件init_env.bat
,该文件将为运行Foobar.exe
设置shell环境
我想编写一个python脚本,它将首先调用init_env.bat
一次,然后调用foobar.exe
多次。然而,我所知道的所有机制(、和backticks)似乎都会为每次执行生成一个新的进程。因此,调用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
@echo off
echo FOO=%FOO%
echo BAR=%BAR%
foobar.bat
@echo off
set FOO=foo
set BAR=bar
@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
文件,则可以从子流程的行中删除shell=True
子句。检查调用(FOOBAR\u exe,shell=True)
除非需要,否则不应传递shell=True
。这里不需要它。@Piotrdorogost经过测试,看起来这两种方式都无关紧要。执行批处理文件时,即使没有shell=True
,它也会生成一个shellsubprocess.check_调用(['foo.bat','>','foo.bat'])
仍然会影响foo.bat
,因此可以说最好将其显式化,这样我们显然需要注意参数。好主意!谢谢对于Python 3的支持,我需要添加var=var.decode('cp1252')
我不得不修改一行k,v=map(str.strip,var.decode().strip().partition('='))
,因为我得到了错误:TypeError:需要一个类似字节的对象,而不是'str'