The shell maintains a set of named values that every process it spawns can read. These are environment variables[1]. They are how the shell knows where to find programs, what your username is, and what terminal you are using. They are also how you configure tools and pass information between processes.
What is in the environment
env # print all environment variables
printenv # same, slightly different format
printenv HOME # print a specific variable
echo $HOME # the shell expands $HOME to its valueSome important ones you already have:
echo $HOME # your home directory: /home/user
echo $USER # your username: user
echo $SHELL # your shell: /bin/bash
echo $PWD # current directory (same as pwd)PATH
$PATH is the most important environment variable. It is a
colon-separated list of directories. When you type gcc and press
Enter, the shell searches each directory in $PATH in order, looking
for a program named gcc. If it finds one, it runs it. If it does
not, you get command not found.
echo $PATHYou will see something like:
/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbinTo add a directory to $PATH:
export PATH="$HOME/.local/bin:$PATH"This prepends ~/.local/bin to the existing $PATH. Now the shell
will check there first. Programs you install locally go in
~/.local/bin and become available without root.
In c05/03
you implement this search in C — getenv("PATH"), split on :, and
access() to test each candidate executable.
Setting variables
MY_VAR="hello" # sets a shell variable
echo $MY_VAR # prints: helloThis sets a shell variable — it exists in the current shell but is not passed to child processes[2].
export MY_VAR="hello" # sets and exports to child processesexport marks the variable so that any process this shell spawns will
inherit it. Without export, MY_VAR is invisible to programs you
run.
unset MY_VAR # remove the variable entirelyMaking it permanent
Variables set in the terminal exist only for the current session.
Close the terminal and they are gone. To make them permanent, add them
to ~/.bashrc:
echo 'export MY_VAR="hello"' >> ~/.bashrc
source ~/.bashrc~/.bashrc is a shell script that Bash runs every time a new
interactive shell starts. source runs it in the current shell
without starting a new one — so your changes take effect immediately.
source ~/.bashrc # reload bashrc in the current sessionThere is a distinction worth knowing: ~/.bashrc runs for interactive
non-login shells — the terminals you open during a normal session.
~/.bash_profile (or ~/.profile on systems that use it) runs for
login shells — SSH sessions, virtual consoles, and some terminal
emulators on first launch. If you add an export to ~/.bashrc and
it does not appear in an SSH session, this is why. The safe fix is to
source ~/.bashrc from ~/.bash_profile if it exists, which most
default configurations already do.
A practical use
Programs can read environment variables the same way the shell does. A common pattern in C programs: a variable that switches behavior — extra output, verbose logging, debug[3] mode. To set one for a single run without exporting it:
DEBUG=1 ./myprogramVAR=value command sets the variable only for that invocation. The
process inherits it; your shell does not. The moment the program exits,
it is gone. This is the right way to change behavior for one run
without polluting your environment.
To make it permanent for the current session:
export DEBUG=1To make it permanent across sessions, add it to ~/.bashrc:
echo 'export DEBUG=1' >> ~/.bashrc
source ~/.bashrcThe programs you write in the C chapters ahead will read variables like
this — checking getenv("DEBUG") in C to decide whether to print
extra information. This page is why that works.