1

According to voithos's answer, os.environ can set environment variables and subprocess automatically inherit from parent process.

However, compare below to cases

First case, in python interaction mode

>>>import os
>>>os.environ['a']='1'
>>>os.system('echo $a')
1
0

The result is fine.

Second case, in bash script

#!/bin/bash
python3 - <<EOF
import os
os.environ['a']='1'
os.system('echo $a')
EOF

save the above as test.bash and run bash test.bash we got nothing!

Why in the second case, os.system doesn't inherit variable?


summary

Any dollar sign $ in bash here document will be expanded by default, no matter it is inside single quotes or not.

One way is to escape $ with backslash \ like \$

There is another way to avoid this expand, that is to single quote the first here doc delimiter, compare following

a=0

python3 - <<here
import os
os.environ['a']='1'
os.system('echo $a')
here

python3 - <<'here'
import os
os.environ['a']='1'
os.system('echo $a')
here
Community
  • 1
  • 1
user15964
  • 2,507
  • 2
  • 31
  • 57
  • Slightly related question: Is your child-process (the python-process) able to set **persistent** environment variables? I know that NodeJS doesn't allow you to set environment variables that persist after the program ends. – geostocker Apr 24 '17 at 08:43
  • 3
    Change `os.system('echo $a')` to `os.system('echo \$a')` – Christos Papoulas Apr 24 '17 at 08:44
  • it inherits variable, but `$a` must be evaluated _before_ because of interactive stuff. I'm using windows and `echo %a%` yields `1` even ran from bash. – Jean-François Fabre Apr 24 '17 at 08:47
  • @ChristosPapoulas I got confused. I thought $a only expand inside double quotes. It should not expand inside single quotes, right? – user15964 Apr 24 '17 at 09:19
  • it's expanded _before_ the command is run, while in the multiline redirect. – Jean-François Fabre Apr 24 '17 at 09:20
  • It's not in *shell* single quotes; the single quotes are literal characters inside the here document, which is treated as a double-quoted string by the shell. – chepner Apr 24 '17 at 12:03
  • @chepner Thank you for explanation, I understand now – user15964 Apr 24 '17 at 14:29

1 Answers1

1

What @ChristosPapoulas says is right. The $a is getting evaluated by the shell when you're typing it in. The $a never makes it to your python interpreter. This can be seen in the following:

$ cat >/tmp/foo <<EOF
> import os
> os.environ['a'] = '1'
> os.system('echo $a')
> EOF
$ cat /tmp/foo
import os
os.environ['a'] = '1'
os.system('echo ')
$
Alex L
  • 1,114
  • 8
  • 11
  • yes, that we saw. But what's the fix? trying `echo \$a` seems to fix it but I cannot test, being on windows. – Jean-François Fabre Apr 24 '17 at 09:19
  • Oh. If you write actual python code with a text editor, and put it in a file, then none of this is a problem, because you can put the `$` in the file just fine. Is that an acceptable solution? – Alex L Apr 24 '17 at 10:48
  • @Jean-FrançoisFabre `\$a` works. I am on windows too. But win 10 has built-in sub linux and bash on windows, so I can confirm – user15964 Apr 24 '17 at 14:59