Skip to content

Linux Variables

Mental model

  • A shell variable lives only in the current shell. export promotes it to an environment variable so child processes inherit it. That's the whole distinction.
  • VAR=value → shell only. export VAR=value → inherited by anything you launch.
  • Inheritance is one-way (parent → child). A child can't change the parent's env — which is why a script can't cd your shell for you.

Setting & inspecting

Command What it does
VAR=value set a shell variable (this shell only)
export VAR=value set + export (children inherit)
VAR=value cmd set for just that one command's run
unset VAR remove it
echo $VAR print one value
printenv / env list exported (environment) variables
set list all shell vars (incl. non-exported)
declare -p VAR show a var + its attributes

Common variables

Variable Meaning
$HOME your home directory
$USER current username
$PATH dirs searched for commands (colon-separated)
$SHELL your login shell (not necessarily current one)
$PWD / $OLDPWD current / previous directory
$LANG locale (language/encoding)
$EDITOR default editor (git, crontab, etc. use it)
$TERM terminal type
$DISPLAY which X display to draw to (see [[display-basics]])
$XDG_SESSION_TYPE x11 vs wayland (see [[display-basics]])

Shell special variables

Variable Meaning
$? exit code of last command (0 = ok)
$$ PID of the current shell
$! PID of the last backgrounded job
$0 name of the script/shell
$# number of args passed to a script
$@ all args

Persistence — where to define them

File When it loads
~/.bashrc every interactive non-login bash shell
~/.bash_profile / ~/.profile login shells
~/.zshrc interactive zsh
/etc/environment system-wide, all users (simple KEY=val, no scripting)

Login vs non-login is the classic "my var works in one terminal but not another" gotcha. A common fix is to source ~/.profile from ~/.bashrc.