Environment Variable Zoo
Environment variables are basically inherited, named arguments to processes with a huge impact on how a Linux or other *nix systems work.
Reading and writing environment variables
These commands here should work in almost all shells inspired by the original sh, if you use something else you probably know why and how to use it.
- Read out a single Variable
echo "$SHELL"
printenv SHELL
- Dump out all variables
export
printenv
- Set one or more variable for a single command
TZ=UTC LANG="de_DE.UTF-8" date
-
env TZ=UTC LANG="de_DE.UTF-8" date
Useful program for simpler shells, environment (un)setting and chain-loading. - Set a variable for the currently running shell
export TC=UTC
declare -x TC=UTC
Persisting Environment Variables
For permanently setting some environment variables there are a number of options (Options further up usually can override the ones below them).
.bashrc
,.zshrc
, etc.- Read whenever you start your favourite shell (as a non-login shell), but don't assume it has effects on the whole session, it is not made for that.
- Your Desktop Environment
- Desktops like setting environment variables derived from their settings, sometimes for single programs, sometimes for the whole session.
.profile
- Read on every login (your login manager is responsible for doing this) and applies to your whole session.
/etc/profile.d/
and/etc/profile
- System-wide
.profile
equivalent, remember that you are sharing this one with your packages. - PAM
- PAM also sets environment variables.
The .bashrc
(plus friends) and .profile
can be reloaded by running source ~/<filename>
or . ~/.filename
.
Note: Non POSIX shells usually have their own .profile
equivalent, keep that in mind when changing your login shell. Bash for example uses .bash_profile
if it exists.
Spying on other Processes
Sometimes it is useful to know what environment variables a given running process has currently set, if the process belongs to you or you have root rights (use them responsibly) you have access to the file that contains the process environment.
The files path is /proc/$pid/environ
(Substitute $pid
for the process id), it contains the null separated environment variables.
To get them in a pretty way one can use the command tr '\0' '\n' < /proc/$pid/environ
(pipe it into the tr command which replaces the null separators with newlines).
htop
shows the selected processes environment when pressing e.
Note: This is the reason why it usually is a bad idea to use environment variables for secrets, they can be read out by any other process running under the same user. When transporting secrets from one program to another use pipes and features of your shell to directly read from and write to them.
Finding Documentation
Outside of the usual online sources: Read the documentation and read the manpages. Most manpages have an ENVIRONMENT
section describing which variables the program reads and/or sets.
Linux and Posix
You can find a more complete list of the standardised variables in the POSIX (2017, the latest at the time of writing) specification.
HOME
- Contains the path to your home directory, as simple as that. (Don't abuse for constructs like
$HOME/.config/whatever
, that's what the XDG home variables are for.) PATH
- Contains a colon separated list of paths to directories that contain binary files for running them as commands. Directories closer to the front can override others counting binaries of the same name further back.
USER
- Should contain the currently logged in username. (Fun fact: the kernel doesn't know your username)
SHELL
- Contains the path to the shell binary configured for the current user, this is probably how your favourite terminal emulator knows about your favourite shell without configuration. This may or may not be the shell you are currently using.
TMPDIR
orTMP
orTEMP
- Almost always one of them contains a path to the preferred temporary directory. Useful for when every user gets their own directory with proper permissions.
TMPDIR
is the one in the POSIX standard and should be the preferred one. LC_*
- These contain locale information and are the reason why language settings work across desktop environments. Unfortunately also the reason why you have to restart applications after changing system preferences. For possible values see
/etc/locale.gen
and/etc/locale.conf
. LANG
- Language setting, not prefixed by
LC_
for reasons. Set toC
for "no translation at all", usually that means American English. For possible values see/etc/locale.gen
and/etc/locale.conf
. TZ
- This contains the current timezone to use i.e.
Europe/Berlin
. EDITOR
- Like
SHELL
, but for your favourite text editor. BROWSER
- Like
SHELL
, but for your favourite browser. (Not standardised anywhere, but a well known convention) TERM
-
Contains the name of the terminal, together with the terminfo database the capabilities of the terminal can be found out. When remoting into other machines with a less well known terminal
xterm
is usually a sane fallback. MOTD_SHOWN
- When set it indicates who has already shown the motd to prevent showing it twice. Convention, probably best known implementation is the pam motd module.
XDG freedesktop.org
Base Directories
These are defines in the Desktop Base Directories Specification, while the below is an overview and you should always read the specification.
Note: while one can usually guess where those directories are, it is always a good idea to respect the environment variables instead of blindly writing to some guessed default path, People trying to organise their Home folder will thank you.
XDG_DATA_HOME
- Path where applications can dump their non-configuration and non-cache persistence.
- Default:
$HOME/.local/share
XDG_CONFIG_HOME
- Path for storing configuration files (and nothing else!)
- Default:
$HOME/.config/
XDG_DATA_DIRS
- colon
:
separated list of fallback directories forXDG_DATA_HOME
containing default data files. (similar to how$PATH
works) - Default:
/usr/local/share/:/usr/share/
XDG_CONFIG_DIRS
- colon
:
separated list of fallback directories forXDG_CONFIG_HOME
containing default configuration files. (similar to how$PATH
works). This behaviour is very useful when administrating large desktop systems. - Default:
/etc/xdg/
XDG_CACHE_HOME
- Path for storing cache files, may contain files specific to the current architecture details, may need cleaning up when on a shared filesystem.
- Also be used for files that better get lost rather than ending up in a backup by accident,
keepassxc
is an example for that. - Default:
$HOME/.cache/
XDG_RUNTIME_DIR
- For temporary runtime files like sockets, pipes, etc.
- Usually:
/run/user/<userid>/
User Directories
There is also the possibility to define User directories, these have the form of XDG_<name>_DIR
and are configured using the $XDG_CONFIG_HOME/user-dirs.dirs
and taken care of by the xdg-user-dirs-update
utility
Commonly specified ones are:
DESKTOP
DOWNLOAD
TEMPLATES
PUBLICSHARE
DOCUMENTS
MUSIC
PICTURES
VIDEOS
SCREENSHOTS
- Used by some popular screenshot scripts
Current Desktop
The Freedesktop "Desktop Entry Specification" specifies a XDG_CURRENT_DESKTOP
variable that is set from the DesktopNames
value in desktops session file (the ones in /usr/share/xsessions/
and /usr/share/wayland-sessions/
and whatever XDG_DATA_DIRS
points to).
It contains a colon separated list of names for the current desktop, primarily intended for activating or deactivating desktop entries (i.e. you don't want the gnome settings cluttering up you KDE menus and vice versa).
XDG Session
These variables are not part of a specification, the best source for them is a guide for "Writing Display Managers" with systemd and the manpage for the pam_systemd
module. Some of them happen to be useful.
XDG_SEAT
- By definition set to
seat0
, probably reserved for future use in multiseat scenarios. XDG_SESSION_TYPE
- The best documentation for this one is probably the
type
argument for the pam_systemd module, roughly it is the display server used for the session. (x11
,wayland
,mir
,tty
,unknown
) XDG_SESSION_CLASS
- either
user
orgreeter
depending on whether the session is primarily logged in or for logging in. XDG_VTNR
- set to the number of the TTY the current session runs in.
XDG_SESSION_ID
- Either the
/proc/self/sessionid
of the auditing session or an "independent counter".
Graphical Environment
DISPLAY
- The id of your X-Display, on your laptop it is probably
:0
. WAYLAND_DISPLAY
- The name of your wayland socket file in
$XDG_RUNTIME_DIR/
. XCURSOR_SIZE
,XCURSOR_THEME
,XCURSOR_PATH
- One way to configure how your cursor looks in most applications. It even works with wayland for when other options are not available. The Arch Wiki has more information on cursor configuration.
DBUS_SESSION_BUS_ADDRESS
- Contains information on how to connect to the dbus session bus. Usually set by the
dbus-run-session
wrapper.
Java
_JAVA_AWT_WM_NONREPARENTING
- Tells java if you have a non-reparenting window manager, usually set to 0 on modern Xorg, to 1 on wayland. If your window stays blank that is an indicator this one is wrong. (Yes the underscore at the start is intentional.)
- Possible Values:
0
,1
More Java environment variables will be added when I run into them.