如何从 Python 执行批处理文件,以便它可以改变调用过程的环境?

Ale*_*ler 5 python windows shell

在Windows中有一个3党的命令行工具,我想在我的python脚本使用。假设它foobar.exe位于C:\Program Files (x86)\foobar. Foobar 附带了一个额外的批处理文件init_env.bat,它将设置foobar.exe要运行的 shell 环境。

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

是否可以通过init_env.bat允许init_env.bat更改调用脚本进程环境的方式从 python调用?

Aya*_*Aya 5

是否可以通过init_env.bat允许init_env.bat更改调用脚本进程环境的方式从 python 调用?

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

否则,在子 shell 中生成它会容易得多,然后调用set以输出新的环境变量,并从中解析输出。

以下对我有用...

init_env.bat

@echo off
set FOO=foo
set BAR=bar
Run Code Online (Sandbox Code Playgroud)

foob​​ar.bat

@echo off
echo FOO=%FOO%
echo BAR=%BAR%
Run Code Online (Sandbox Code Playgroud)

主文件

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()
Run Code Online (Sandbox Code Playgroud)

...对于哪些python main.py输出...

FOO=foo
BAR=bar
FOO=foo
BAR=bar
Run Code Online (Sandbox Code Playgroud)

请注意,我仅使用批处理文件代替您的批处理文件,foobar.exe因为我手头没有.exe可以确认环境变量已设置的文件。

如果您使用的是.exe文件,则可以shell=True从 lines 中删除该子句subprocess.check_call(FOOBAR_EXE, shell=True)