1

I want to set environment variables in a shell and then use those variables in subsequent commands; however using subprocess.call() in shell mode does not keep the environment variable set. How do I get the desired functionality through subprocess.

Here is a simplified example of a problem I am having:

import subprocess
#Method 1
subprocess.call('VARNAME1=\"MyValue1\"', shell=True)
subprocess.call("echo $VARNAME1", shell=True)

#Method 2
subprocess.call('VARNAME2=\"MyValue2\"; echo $VARNAME2', shell=True)

Output:

> 
> MyValue2

Expected Output:

> MyValue1
> MyValue2

I will not be able to string the commands together with ";" as I did in the second method.

Thanks for the help.

digitaLink
  • 458
  • 3
  • 17
  • 3
    Each run of `subprocess.call` runs a new shell. They cannot share this way. If you need to set environment variables for the spawned shell use the `env` kwarg to the `call` function. – Etan Reisner Oct 14 '15 at 01:13
  • Would using PIPE be the best way to pass subsequent commands to the same shell process? – digitaLink Oct 14 '15 at 01:50
  • Hm? No. `PIPE` doesn't let you tack arbitrary commands on later. Oh, I suppose you could `PIPE` standard input to an "interactive" shell session and send it commands on standard input... yes. That seems very ugly to me though. Do your shell commands set variables that you need for later shell calls or do they just all share common externally set environment variables? – Etan Reisner Oct 14 '15 at 01:56
  • Maybe my example wasn't as clear as I originally thought. I want to call some commands that source a bash script to set environment variables for a shell, then to be able to send several commands to that shell from my python script. – digitaLink Oct 14 '15 at 02:02
  • Do the scripts *themselves* share variables between them (script A sets a variable that script B then uses?) or just the common environment variables? Because the latter is relatively easily accomplished by running the original script and using python to put those variables into an environment table that is then passed to `call` in the `env` kwarg. – Etan Reisner Oct 14 '15 at 02:05
  • That may work. If for example I want to start a program that requires environment variables to be set, I could pass those using the env keyword in the call statement that starts the program. I guess since I had a several commands that may be sent I was hoping there was a way to continue sending commands to the shell that was created. Thanks for all of the help by the way. – digitaLink Oct 14 '15 at 02:10
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/92206/discussion-between-digitalink-and-etan-reisner). – digitaLink Oct 14 '15 at 02:12
  • related: [Calling the “source” command from subprocess.Popen](http://stackoverflow.com/q/7040592/4279) – jfs Oct 14 '15 at 06:39

1 Answers1

1

To set environment variables you must use the os.environ array

For example:

import os    
os.environ['VARNAME1'] = "My value"
Andrei Tumbar
  • 490
  • 6
  • 15
  • 1
    That's the environment of the python script itself. Which is then inherited by any processes the python script then runs but `subprocess.call` has an *explicit* argument to override that and use a custom environment for the spawned process. The `env` kwarg. – Etan Reisner Oct 14 '15 at 02:06
  • @EtanReisner: So what is the solution? Could you please write an answer? – Vinayak Kaniyarakkal Jun 05 '18 at 11:50
  • @VinayakKaniyarakkal An answer to what question? This question was not the clearest which is why it ended up where it was. I discussed a bit more in the chat with the OP but didn't get much farther than "use the `env` kwarg if you need to specify env vars to subprocess run commands, if you need to get vars back from the shell there are likely better approaches than this entire approach. – Etan Reisner Jun 22 '18 at 19:57