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
- Dump out all variables
- 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" dateUseful program for simpler shells, environment (un)setting and chain-loading.
- Set a variable for the currently running shell
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).
- 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.
- Read on every login (your login manager is responsible for doing this) and applies to your whole session.
.profileequivalent, remember that you are sharing this one with your packages.
- PAM also sets environment variables.
.bashrc (plus friends) and
.profile can be reloaded by running
source ~/<filename> or
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
$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.
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.
- 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.)
- 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.
- Should contain the currently logged in username. (Fun fact: the kernel doesn't know your username)
- 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.
- 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.
TMPDIRis the one in the POSIX standard and should be the preferred one.
- 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
- Language setting, not prefixed by
LC_for reasons. Set to
Cfor "no translation at all", usually that means American English. For possible values see
These describe the current timezone to use i.e.
Europe/Berlin. Usually points to a tzfile in
- A program that can be run using
sh -cthat shows a textfile (unually in the current terminal)
PAGER, but for your favourite text editor.
BROWSER, but for your favourite browser. (Not standardised anywhere, but a well known convention)
PAGERbut for opening
mailto:links with your favourite E-Mail writer. (Also never standardised)
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
xtermis usually a sane fallback.
- 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.
Note: What is meant by run with
sh -c is demonstrated pretty well by debians sensible-utils. In a nutshell you lauch your favorite
sh -c "$EDITOR \"\$@\"" EDITOR <filepath-goes-here>
Note: I'm trying to move the
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 😞.
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.
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.
- Path where applications can dump their non-configuration and non-cache persistence.
- Path for storing configuration files (and nothing else!)
:separated list of fallback directories for
XDG_DATA_HOMEcontaining default data files. (similar to how
:separated list of fallback directories for
XDG_CONFIG_HOMEcontaining default configuration files. (similar to how
$PATHworks). This behaviour is very useful when administrating large desktop systems.
- 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,
keepassxcis an example for that.
- For temporary runtime files like sockets, pipes, etc.
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
Commonly specified ones are:
SCREENSHOTS- Used by some popular screenshot scripts
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/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).
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.
- By definition set to
seat0, probably reserved for future use in multiseat scenarios.
- The best documentation for this one is probably the
typeargument for the pam_systemd module, roughly it is the display server used for the session. (
greeterdepending on whether the session is primarily logged in or for logging in.
- set to the number of the TTY the current session runs in.
- Either the
/proc/self/sessionidof the auditing session or an "independent counter".
- The id of your X-Display, on your laptop it is probably
- The name of your wayland socket file in
- 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.
- Contains information on how to connect to the dbus session bus. Usually set by the
- 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:
More Java environment variables will be added when I run into them.
The path to a yaml file containing connection information for a Kubernetes cluster that tools like
helmcan use to connect to the cluster.
- k3s generates a
/etc/rancher/k3s/k3s.yamlfile you can point this at.