How to execute batch file from Python so that it could alter environment of the calling process?
python, shell, windows
Solution
Is it possible to call `init_env.bat` from python in a way that allows `init_env.bat` to alter the environment of the calling scripts process?
Not easily, although, if the `init_env.bat` is really simple, you could attempt to parse it, and make the changes to `os.environ` yourself.
Otherwise it's much easier to spawn it in a sub-shell, followed by a call to `set` to output the new environment variables, and parse the output from that.
The following works for me...
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()
...for which `python main.py` outputs...
FOO=foo
BAR=bar
FOO=foo
BAR=bar
Note that I'm only using a batch file in place of your `foobar.exe` because I don't have a `.exe` file handy which can confirm the environment variables are set.
If you're using a `.exe` file, you can remove the `shell=True` clause from the lines `subprocess.check_call(FOOBAR_EXE, shell=True)`.
Problem
On Windows there's a 3rd party command line tool I would like to use in my python script. Let's say it's `foobar.exe` located under `C:\Program Files (x86)\foobar`. Foobar comes with an additional batch file `init_env.bat` that will set up the shell environment for `foobar.exe` to run. I want to write a python script, that will first call `init_env.bat` once and then `foobar.exe` multiple times. However, all mechanisms I know of (subprocess, os.system and backticks) seem to spawn a new process for each execution. Therefore, calling `init_env.bat` is useless, because it does not change the environment of the process in which the python script runs and thus every subsequent call to `foobar.exe` fails, because it's environment is not set up. Is it possible to call `init_env.bat` from python in a way that allows `init_env.bat` to alter the environment of the calling scripts process?