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.
Table of Contents
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 TZ=UTC
declare -x TZ=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
andTZDIR
-
These describe the current timezone to use i.e.
Europe/Berlin
. Usually points to a tzfile in/usr/share/zoneinfo/
PAGER
- A program that can be run using
sh -c
that shows a textfile (unually in the current terminal) EDITOR
- Like
PAGER
, but for your favourite text editor. BROWSER
- Like
BROWSER
, but for your favourite browser. (Not standardised anywhere, but a well known convention) MAILER
- Like
PAGER
but for openingmailto:
links with your favourite E-Mail writer. (Also never standardised) 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.
NO_COLOR
- When set to a non-empty string Software shouldn't use ANSI-colors unless explicity configured to do so. See no-color.org
Note: What is meant by run with sh -c
is demonstrated pretty well by debians sensible-utils. In a nutshell you lauch your favorite EDITOR
using sh -c "$EDITOR \"\$@\"" EDITOR <filepath-goes-here>
Note: I'm trying to move the BROWSER
and MAILER
variables to the XDG section. See the related discussion on the xdg mailing list. You'll have to dig around a bit to find all mails 😞.
XDG freedesktop.org
freedesktop.org hosts quite a few specifications ensuring interoperability of free (software) desktop envoirnments, these specifications happen to contain quite a lot of envoirnment variables.
XDG stands for Cross Desktop Group.
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.
Mozilla
These are used for Firefox, Thunderbird and other programs that are built on top of Firefox.
MOZ_ENABLE_WAYLAND
- If set it enables wayland support for all mozilla programs (if not already enabled by default) typically set to
1
.
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.
Kubernetes
KUBECONFIG
-
The path to a yaml file containing connection information for a Kubernetes cluster that tools like
kubectl
andhelm
can use to connect to the cluster. - k3s generates a
/etc/rancher/k3s/k3s.yaml
file you can point this at.