Where to start First steps track · 15 stages
Linux Labs

Environment variables and PATH

4 min bash

Environment variables: env, export, $PATH, ~/.bashrc and profiles; where "command not found" comes from.

Cheat sheet

6 commands Printable version
  • echo "$PATH" its value
  • env all environment variables
  • printenv HOME a single variable
  • export VAR=value for the current session + children
  • VAR=value cmd for one command only
  • source ~/.bashrc reload without a new login
  • permanent: ~/.bashrc (terminal) · ~/.profile (login/SSH) · /etc/environment (system-wide)
  • systemd: Environment= / EnvironmentFile= ; cron: inside the script

Overview

Environment variables configure program behavior. The most important is PATH (where to look for executables).

bash
echo $PATH                        # where commands are looked up
env                               # all environment variables
printenv HOME                     # one variable
echo "$HOME $USER $SHELL"         # common ones

Options

bash
export VAR=value                  # for the current shell and CHILD processes
VAR=value command                 # for one command only
unset VAR                         # remove it
export PATH="$PATH:/opt/bin"      # append a directory to PATH
export PATH="/opt/bin:$PATH"      # ...prepend it (higher priority)
set                               # ALL shell variables (including non-exported)

The difference: a variable without export is visible only to the current shell; with export, it's inherited by processes started from it.

Recipes

1

Where to save it (login vs. non-login)

File When it's read
~/.bashrc interactive non-login shells (a new terminal/tab)
~/.profile / ~/.bash_profile login shells (SSH login/console login)
/etc/profile, /etc/profile.d/*.sh system-wide for login shells
/etc/environment system-wide for everyone (plain KEY=value, no export)

A subtlety: an SSH login is a login shell (reads ~/.profile), while a new terminal in an already-open session is non-login (reads ~/.bashrc). That's why Ubuntu's ~/.profile sources ~/.bashrc. source file (or .) reloads it without a new login.

Troubleshooting

5

command not found, even though the binary exists

Its directory isn't in $PATH. Check echo $PATH; add the directory or call it by its full path. For something freshly installed, sometimes hash -r (reset the path cache) or a new shell helps.

export worked, but disappeared in a new terminal

export only lives in the current session. To make it permanent, add it to ~/.bashrc (terminals) or ~/.profile (login), then source it or log back in.

The variable is set in the terminal but not over SSH (or vice versa)

Different files for login/non-login (see the table). SSH reads ~/.profile, but you set it in ~/.bashrc — move it, or have one source the other.

A script/cron/systemd doesn't see the variable

cron and systemd units do not read your ~/.bashrc. Set it explicitly: Environment=/EnvironmentFile= in the unit, or inside the script itself for cron.

sudo "loses" variables

sudo resets the environment (env_reset). Pass it through: sudo -E cmd (if allowed) or sudo VAR=val cmd (see sudo).

Terms

2
environment variable
A NAME=value pair in a process environment; child processes receive a copy. In Bash, export adds a variable to the environment, and env prints the environment. Also appears in: Docker, docker compose, Dockerfile, Bash scripts: running, variables, arguments and 4 more
PATH
An environment variable holding a colon-separated list of directories where the shell looks up a command given without a /. command -v or which shows which file will run. Also appears in: nginx, Paths, which / type / whereis, hash and 66 more

See also

  • files-basics — Navigation and files — ls, cd, cp, mv, rm, cat, less, head, tail, terminal copy-paste.
  • systemd — The init system and service manager (PID 1): units, targets, dependencies, journals.
Loading…