4

I am working on converting an older system of batch files to python. I have encountered a batch file that sets the environment variables for the batch file that called it. Those values are then used again in future calls to batch files. My environment variables seem to go down the flow of calls but I am unable to bring them back up. I have read two different threads on here that talk about something similar but its not exactly the same. Is it possible to retrieve these environment variables from the subprocess?

Python subprocess/Popen with a modified environment

Set Environmental Variables in Python with Popen

What I am doing now:

p = Popen(process_, cwd=wd, stdout=PIPE, shell=True,
          universal_newlines=True, stderr=STDOUT, env=env)

The old flow of bat files:

foo.bat calls foo-setparam.bat
foo-setparam.bat sets some variables
foo.bat uses these variables
foo.bat calls bar.bat
bar.bat uses variables set by both foo.bat and foo-setparam.bat

Update: I have tried adding "call " in front of my popen parameter. I got the same behavior.

Community
  • 1
  • 1
Nickolouse
  • 191
  • 14
  • I'm not sure what you mean by _a batch file that sets the environment variables for the batch file that called it_. It's not possible for a subprocess to alter the environment of the calling process. At best a batch file could return some output to the caller, which the caller could examine and then decide to alter its own environment. – John Gordon Jul 12 '16 at 16:44
  • 1
    From my understanding in a .bat file the call command runs the targeted .bat file in the same environment. – Nickolouse Jul 12 '16 at 16:50
  • 2
    Any Batch file that is called via `call subprog.bat` AND that does _NOT_ contain a `setlocal` command can alter the environment of the caller Batch file... – Aacini Jul 12 '16 at 16:50
  • I didn't realize `call` was being used. My mistake. – John Gordon Jul 12 '16 at 16:52
  • @JohnGordon Not a problem. I updated my question to better reflect the use case to help eliminate confusion. – Nickolouse Jul 12 '16 at 16:54
  • @eryksun yes it is the path to the batch file. I do plan to replace it with python. – Nickolouse Jul 12 '16 at 17:59
  • @eryksun Yes this is the ideal long term goal but for the time of transition I need to be able to interface my code into the old code without modifying the old code. – Nickolouse Jul 12 '16 at 18:25
  • For now, you can do what [`distutils/_msvccompiler. _get_vc_env`](https://hg.python.org/cpython/file/v3.6.0a3/Lib/distutils/_msvccompiler.py#l76) does. Note that it intentionally doesn't use `shell=True` in order to be able to use `cmd /u` to have `set` output the environment as Unicode. Otherwise some environment variables may be corrupted when output using the current console codepage (or ANSI if there's no console attached to the process). – Eryk Sun Jul 12 '16 at 18:50
  • For example: `out = subprocess.check_output('cmd.exe /u /c "{}" && ((echo :ENVIRONMENT:) & set)'.format(process_), stderr=subprocess.STDOUT, env=env, cwd=wd);` `out, env_out = out.split(':ENVIRONMENT:\r\n'.encode('utf-16le'));` `env_out = env_out.decode('utf-16le', errors='replace')`. The value of `env_out` can now be split into a dict using a comprehension just like `_get_vc_env` does. – Eryk Sun Jul 12 '16 at 18:54

1 Answers1

1

It's generally not possible for a child process to set parent environment variables, unless you want to go down a mildly evil path of creating a remote thread in the parent process and using that thread to set variables on your behalf.

It's much easier to have the python script write a temp file that contains a sequence of set commands like:

set VAR1=newvalue1
set VAR2=newvalue2

Then modify the calling batch file to call your python script like:

python MyScript.py
call MyScript_Env.cmd
Anon Coward
  • 9,784
  • 3
  • 26
  • 37
  • Unfortunately I am not able to modify the existing batch files. – Nickolouse Jul 12 '16 at 20:39
  • Sorry, I misunderstood, do you need to see the env variables from batch file that's called by python? – Anon Coward Jul 12 '16 at 20:41
  • Sorry for the long turn around I was taken off this task for a while. Yes I need to access environment variables in python that were set by a batch file called from the same python script. – Nickolouse Aug 26 '16 at 21:04