66

I am on ubuntu 13.04, bash, python2.7.4

The interpreter doesn't see variables I set.

Here is an example:

$ echo $A
5
$ python -c 'import os; print os.getenv( "A" )'
None
$ python -c 'import os; print os.environ[ "A" ]'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/usr/lib/python2.7/UserDict.py", line 23, in __getitem__
    raise KeyError(key)
KeyError: 'A'

But everything works fine with the PATH variable:

$ echo $PATH 
/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
$ python -c 'import os; print os.getenv("PATH")'
/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

And it notices changes in PATH:

$ PATH="/home/alex/tests/:$PATH"
$ echo $PATH 
/home/alex/tests/:/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
$ python -c 'import os; print os.getenv("PATH")'
/home/alex/tests/:/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

What could be wrong?

PS the problem comes when using $PYTHONPATH:

$ python -c 'import os; print os.getenv("PYTHONPATH")'
None
xealits
  • 4,224
  • 4
  • 27
  • 36

3 Answers3

115

Aha! the solution is simple!

I was setting variables with plain $ A=5 command; when you use $ export B="foo" everything is fine.

That is because export makes the variable available to sub-processes:

  • it creates a variable in the shell
  • and exports it into the environment of the shell
  • the environment is passed to sub-processes of the shell.

Plain $ A="foo" just creates variables in the shell and doesn't do anything with the environment.

The interpreter called from the shell obtains its environment from the parent -- the shell. So really the variable should be exported into the environment before.

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
xealits
  • 4,224
  • 4
  • 27
  • 36
9

Those variables (parameters in bash terminology) are not environment variables. You want to export them into the environment, using export or declare -x. See the bash documentation on environment.

Yann Vernier
  • 15,414
  • 2
  • 28
  • 26
  • hey! terminology is vague: http://docs.python.org/2/using/cmdline.html#environment-variables – xealits Sep 28 '13 at 19:18
  • Not sure which term you're complaining about, but the issue lies with bash. Python has no control over which variables bash puts in the environment. – Yann Vernier Sep 28 '13 at 19:21
  • I mean that if it is a "parameter" or "variable" -- doesn't matter to me. I care about setting `PYTHONPATH` to work. Though, I see your point -- you mean that assignment `$ A=5` doesn't make an environment variable at all. There is a list of variables in the shell, called "environment". It is passed to sub-processes. And `export` declares some variables in that list (exports them into it). Plain assignment doesn't create variables in that list -- it puts them somewhere else. I'll correct my answer according to all of this. – xealits Sep 28 '13 at 19:32
0

Adding as I do not see an answer that has the exact issue I had. If you have multiple "shells" eg BASH and Z-Shell, ensure that you have exported the environment in the correct shell and that this is available to python.

If you are using VSCode and set the default shell to Z shell, then understandably, variables in .bashrc will not be visible to the python interpreter if they do not also exist in .zshrc. The solution then is to export the variable in both shells or change the default shell to the one with the necessary variables.

NelsonGon
  • 13,015
  • 7
  • 27
  • 57