The printenv command lists a number of environment variables most of which I have not defined. From where does it read these values? Where are the environment variables stored in Linux? strace printenv gave an indication to me that it opens /usr/lib/locale/locale-archive but I did not get a clear idea.
2 Answers
They are not defined in one single place. When your shell starts it usually reads a bunch of initializing scripts that set some environment variables, like for example /etc/profile
and for example in the case of Bash also /etc/bashrc
and ~/.bashrc
. But this depends mostly on your distribution and your shell.
On top of this, a lot of applications that you are probably running, like for example X11 or your terminal emulator will set more variables in your environment.
So, as you see, these variables come from many different places. With strace
you could see where they are read from if they were being set at the execution time of printenv
, but that's not the case, because they are set earlier and kept in memory.
I don't know of any good way to trace back where a variable that has been set has come from. But for example if you use Bash you could start it with the --verbose
parameter to at least see which files it's reading on start up. Like bash --verbose
.
-
1The environment variable PS1 is not shown in printenv command result whereas bash sets it. I can even see it by echo $PS1. Why then does printenv not display it?– JayCommented Jan 1, 2014 at 14:53
-
1Commands env and export list only variables which are exported. $PS1 is usually not exported. That also count's for printenv, it's from here: superuser.com/questions/663069/…– replayCommented Jan 1, 2014 at 15:00
-
1You can view all the environment variables in your shell, whether exported or not, by typing
set
Commented Jan 1, 2014 at 15:37 -
2@MarkPlotnick If they aren't exported, then they aren't environment variables, only shell variables. Commented Jan 1, 2014 at 23:02
Processes inherit environment variables from their parent, they don't read them from a file. Most programs have the same environment variables as the program that started them and never modify them.
When you log in, a number of environment variables are set by the login system. The details depend on the distribution and specific system configuration. You can expect to find HOME
and PATH
everywhere, and USER
, LOGNAME
, MAIL
and SHELL
are very common.
On most systems, environment variables can also be listed in /etc/environment
and ~/.pam_environment
; these files are read when you log in by any method. When you log in to an interactive shell (in text mode or over SSH), or often but not always when you log in in graphical mode (it depends on the display manager,
the session manager and the distribution), the shell reads /etc/profile
and ~/.profile
(or possibly other files depending on the shell and the setup). These files, as well as other files and programs involved in the login process, often define environment variables.
There's no miracle recipe to find out which program or configuration causes an environment variable to be set. You can look for definitions in your configuration files and the system configuration files:
grep -rs SOMEVAR /etc ~/.[!.]*
This won't find environment variable names that are hard-coded in applications. You can also look at different processes to see which ones have it, which gives an indication of which one set it. On Linux, the following command shows the environment variables of process 1234:
tr \\0 \\n </proc/1234/environ | sort
Note that shells have their own variables which are not environment variables. An assignment in a shell script or on the command line (VAR=VALUE
) sets a shell variable; if the variable is exported (export VAR=VALUE
or export VAR
after VAR
has a value), it becomes an environment variables that is visible by child processes. All environment variables automatically become shell variables.