0

While using Pythons subprocess module I noticed it does not seem like environment variables are being set properly. The following is an example from an IPython session showing this:

In [21]: subprocess.check_output(["echo", "$DUMMY"], env={"DUMMY" : "321"}, shell=True)
Out[21]: b'\n'

In [22]: subprocess.check_output(["echo", "$DUMMY"], env={"DUMMY" : "321"})
Out[22]: b'$DUMMY\n'

I get that the second one does not work, as it is not run by a shell. But the first one is the result you get when echoing a variable that is not set. So why does this not work? Or more probably, what am I doing wrong?

tripleee
  • 175,061
  • 34
  • 275
  • 318
Bendik
  • 1,097
  • 1
  • 8
  • 27
  • I rolled back your edit -- your question should remain strictly a question. – tripleee Feb 19 '19 at 12:04
  • @tripleee Sure, this works. I added it for completeness when your answer did not contain a complete code solution. I agree it's better placed in your answer like it is now. – Bendik Feb 19 '19 at 12:56
  • Replace `echo $DUMMY` with `env`. You'll see that the env var is in fact set. Hint: Do arbitrary commands like `/bin/echo` perform var expansion (e.g., `$DUMMY` => `321`) or is it the responsibility of a specific program? – Kurtis Rader Feb 19 '19 at 19:33

1 Answers1

3

Variable interpolation is a shell feature; without a shell, the string you are attempting to echo is simply literally $DUMMY.

You can add shell=True and then of course change the first argument to be a string instead of a list;

subprocess.check_call('echo "$DUMMY"', env={"DUMMY": "321"}, shell=True)

... or figure out a way to pass the second argument in the list directly from Python.

A better test case than echo is env; then you can see that it does in fact set the variable just like you asked it to.

tripleee
  • 175,061
  • 34
  • 275
  • 318
  • 1
    Aha, so when using `shell=True`, I should give the command as a string, not as a list. Did not know that, works when I fix this. Knew it had to be something silly on my part, but couldn't figure it out. Thanks! – Bendik Feb 19 '19 at 11:58
  • I have been struggling with this confusion. Thank you. Is there a way to load the content of a bashrc file for example? – BND May 16 '19 at 06:57
  • 1
    @BND There is of course, but you really want to avoid that,. There are several duplicates around this topic; https://stackoverflow.com/questions/27553576/load-environment-variables-of-bashrc-into-python shows one way to do it, but you probably want to find questions about why this is actually a bad idea. – tripleee May 16 '19 at 07:00