0

I am using a .bat file to:

  1. Set environment variables
  2. Kick off a Python program (that uses these environment variables)
@ECHO OFF
REM TODO: figure out why Python can't see this
SET MY_ENV_VAR="foo"

CALL C:\code\repo\venv\Scripts\activate
CD /d C:\code\repo
@ECHO ON
REM kick off Python, where os.getenv can't see MY_ENV_VAR
CMD /k run_python_console_script

If you're curious, the run_python_console_script kicks off a command made via an Entry Point.

When I run os.getenv("MY_ENV_VAR") it doesn't return "foo", it returns None. Why is this?

I don't want to use SETX (docs), I want the environment variable scoped to just this batch script.


Other Answers

How to access Batch Script variables in python? and Python Subprocess Does not Get Environment Variable from Bat File want to invoke a .bat script as a subprocess. I don't want to do this, the .bat script is my parent process.

virtualenvwrapper supports a postactivate script (see How can I use a postactivate script using Python 3 venv? and Set specific environment variables activating a Python virtual environment) but I am not using virtualenvwrapper.

Intrastellar Explorer
  • 3,005
  • 9
  • 52
  • 119
  • 1
    Perhaps it's due to the venv? I don't have a lot of experience with venvs, but I can imagine that activating the venv would leave you with a fresh environment. – John Gordon May 25 '22 at 13:38
  • 1
    Please read my answer on [Why is no string output with 'echo %var%' after using 'set var = text' on command line?](https://stackoverflow.com/a/26388460/3074564) It makes a big difference if the environment variable `MY_ENV_VAR` is defined with `SET MY_ENV_VAR="foo"` (not recommended) or with `SET "MY_ENV_VAR=foo"` (recommended, but requires enabled command extensions which are enabled by default). So my first suggestion is using in the batch file below `@ECHO OFF` the command line `SETLOCAL ENABLEEXTENSIONS DISABLEDELAYEDEXPANSION` to defined the required execution environment completely. – Mofi May 27 '22 at 12:52
  • My second suggestion is changing `SET MY_ENV_VAR="foo"` to `SET "MY_ENV_VAR=foo"`, run the batch file and check if the Python script using [os.environ\["MY_ENV_VAR"\]](https://docs.python.org/3/library/os.html#os.environ) returns now the string `foo` or __null__ or using [os.getenv("MY_ENV_VAR",default="undefined")](https://docs.python.org/3/library/os.html#os.getenv) and check if that returns the string `foo` or the string `undefined`. – Mofi May 27 '22 at 13:03

2 Answers2

1

Thank you to @Mofi for many possible things to try in the comments section!

The gotcha was in first comment linking to here (placement of "" around the environment variable): https://stackoverflow.com/a/26388460/11163122

REM TODO: figure out why Python can't see this
SET MY_ENV_VAR="foo"

REM DONE: this works (quotes on outside)
SET "MY_ENV_VAR=foo"

It seems the venv activation was not clobbering preexisting environment variables, as @JohnGordon speculated in the comments.

When pip installed on Windows, the run_python_console_script Entry Point is installed into the venv as venv\Scripts\run_python_console_script.exe.

Mofi
  • 46,139
  • 17
  • 80
  • 143
Intrastellar Explorer
  • 3,005
  • 9
  • 52
  • 119
0

From https://ss64.com/nt/set.html

Changes made using the SET command are NOT permanent, they apply to the current CMD prompt only and remain only until the CMD window is closed.

To permanently change a variable at the command line use SetX

John Gordon
  • 29,573
  • 7
  • 33
  • 58
  • 2
    Not relevant, sorry. A process started BY this process should inherit this process's environment. Certainly does with a Delphi executable designed to show a user-set variable. – Magoo May 25 '22 at 02:45
  • Thanks for the answer. Sadly, `SETX` would cause an environment variable collision for me; I had called out in the question description that I am not interested in `SETX`. – Intrastellar Explorer May 25 '22 at 07:03
  • This is answer indeed not relevant here because of the environment variable is defined in the memory of `cmd.exe` processing the batch file which is copied by [CreateProcess](https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessw) into the memory of `cmd.exe` started at end of the batch file and copied once again by `CreateProcess` into the memory of `python.exe` started by second `cmd.exe`. – Mofi May 27 '22 at 13:41
  • So the environment variable must not be defined persistent stored for current user or local machine using `setx` which does not modify the environment of currently running `cmd.exe` process and therefore does not define the environment variable for second `cmd.exe` and for `python.exe` started next. I recommend to read chapters B) and F) in my answer on [What is the reason for "X is not recognized as an internal or external command, operable program or batch file"?](https://stackoverflow.com/a/41461002/3074564) F) explains step by step with an example the environment variable management. – Mofi May 27 '22 at 14:01