How to view Python environment variables

To view the environment variables in Python and query for a particular one:

import os
print(os.environ)  # Print a dict of env vars and their values
os.environ["PYTHONPATH"]  # Query a specific env var

Python picks up these environment variables from your shell when it is first invoked. So this is useful to check if your shell environment variables and their values are being correctly imported into Python.

How to set environment variable in gdb

GDB inherits the environment variables from your shell. Some environment variables, like LD_LIBRARY_PATH, might not be inherited for safety reasons. This can cause errors like this when you try to debug:

$ gdb --args ./a.out
(gdb) r
/path/to/a.out: error while loading shared libraries: libfoobar.so.5: cannot open shared object file: No such file or directory

You can set the LD_LIBRARY_PATH environment variable at the gdb shell using the set env command like this:

(gdb) set env LD_LIBRARY_PATH /path/to/1:/path/to/2

However, if you use a shell like Fish, you will notice that this will silently not work and you still get the cannot open shared object file error.

This is because under the covers, gdb is reading the SHELL environment variable to understand what is the shell and doing what is right for that shell. It might not understand how to work with the Fish, which is a relatively new shell.

The solution that works for me, is to set the SHELL variable at the Fish shell to the Bash path:

$ set SHELL (which bash)

And then launch gdb and set the environment variable as shown above. It works after that.

Reference: Your program’s environment (GDB Manual)

How to list environment variables used by program

Problem

Many programs fail or behave mysteriously because they are looking for or reading environment variables that you may not be aware of. It would be very useful if you could see what environment variables they are probing for.

Solution

If the program is using the getenv standard library call, then you can list all those calls, the environment variable requested for and what value was returned using ltrace:

$ ltrace -e getenv ./your_program

You will be surprised how many environment variables you had no idea about are probed by common programs that you use. I find this usage to be immensely useful in increasing my understanding of any program I use.

How to use shell environment variables in CMake

Many developer SDKs and libraries set their own environment variables. For example, installing OpenNI2 sets OPENNI2_INCLUDE to the path containing its header files. It would be convenient to use these shell environment variables directly in CMake without having to create another CMake variable for it.

This can be done in CMake easily. For example to set the above environment variable as an include directory:

include_directories(
    /home/joe/globespin/include
    $ENV{OPENNI2_INCLUDE}
)

Tried with: CMake 2.8.12.2 and Ubuntu 14.04

PATH environment variable in sudo

Using sudo is a common, safe and recommended method to execute commands that require superuser privileges. However, this command resets the PATH environment variable. So, some badly written installation scripts that require a particular PATH will fail in strange ways when run as sudo.

Here is some useful information about sudo and the PATH environment variable:

  • To ensure safety, sudo by default does not use the PATH environment variable of the user or that of root.

  • sudo also ignores the system-wide environment variables set in /etc/environment or in /etc/profile.d/*.sh.

  • The PATH variable for sudo is hardcoded to /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

  • If you really want sudo to pick up the system-wide PATH or other environment variables, then try this:

    1. Set the PATH or environment variable in a new file named /etc/profile.d/name_anything.sh using export
    2. Start root shell using sudo su -
    3. Check if your path is correct: echo $PATH
    4. Run the command that requires superuser privilege.
  • Reference:

Tried with: Ubuntu 14.04

Environment variables in Fish

Environment variables can be set just like any other variable in the Fish shell.

  • To export an environment variable to the shell, add it in ~/.config/fish/config.fish:
set -x FOO_ENV_VAR /home/joe/bin/some_foo_dir
  • If this a environment variable with many values, then set it as an array. In Fish, you set an array variable with a space-delimited series of values:
set -x FOO_ENV_VAR /home/joe/bin/some_foo_dir /usr/local/foo_dir

Under Bash, you might have set this same environment variable in ~/.bashrc as:

export FOO_ENV_VAR=/home/joe/bin/some_foo_dir:/usr/local/foo_dir
  • If the environment variable with many values already exists and you want to prepend or append a value to it, the technique is the same. For example, to prepend to PATH:
set -x PATH /home/joe/bin/some_foo_dir $PATH
  • Three special environment variables: PATH, CDPATH and MANPATH are treated differently by Fish. These arrive from the environment to Fish as colon-separated, they are converted to array so we can set them easily as shown above using space-delimiter and then they are sent back to the environment as colon-separated. This logic can be seen in the Fish source code file src/env.cpp here. This is also explained in this issue.

  • The problem now is that there are many other environment variables which need to be colon-delimited, but Fish does not do that. For example, the dynamic linker ld.so that is used to load up DLLs when a binary executes requires LD_LIBRARY_PATH environment variable to be colon-delimited. I got errors when this variable was set using space-delimiters: cannot open shared object file: No such file or directory

  • If you run into any problems with an environment variable that takes a series of values, then check back to see how it is set in traditional shells like Bash. If it is colon-delimited there, then you might need to make it colon-delimited in Fish too. But, do remember to enclose it in double quotes for variable expansion to work correctly. For example:

set -x FOO_ENV_VAR "/home/joe/bin/some_foo_dir:$FOO_ENV_VAR"

Tried with: Fish 2.2 and Ubuntu 14.04