student@ubuntu:~$
unix-foundations Lesson 2 9 min read

Shell Environment

PATH, .bashrc, environment variables, and configuring your shell

Reading: Shotts, The Linux Command Line: pp. 147–155 (environment, PATH, .bashrc, aliases) + pp. 93–103 (expansion & quoting)

Quick check before you start: Can you explain what happens when you type ls at the prompt? If you know the shell searches PATH to find /usr/bin/ls, skip to Shell Startup Files. If not, read on.

Practice this topic: Shell Environment skill drill

After this lesson, you will be able to:

  • Explain what environment variables are and how they differ from shell variables
  • Describe how the shell uses PATH to locate commands
  • Modify ~/.bashrc to make aliases and variables persistent
  • Use source to reload shell configuration without opening a new terminal

Environment Variables

The shell maintains a set of variables that store configuration values. Programs you launch can read these variables to determine how to behave.

View the important ones:

echo $HOME       # /home/student
echo $USER       # student
echo $SHELL      # /bin/bash
echo $PATH       # colon-separated list of directories

See every environment variable at once with env:

env | head -10

Shell Variables vs. Environment Variables

A shell variable exists only in your current shell session:

MY_NAME="Alice"
echo $MY_NAME        # Alice

An environment variable is visible to child processes — any program you launch from the shell:

export GREETING="Hello from the shell"
echo $GREETING       # Hello from the shell

Without export, a variable stays local. With export, every program you run inherits it. In C, getenv("GREETING") only sees exported variables.

Common Pitfall: Variable assignment requires no spaces around =. Writing X=5 works. Writing X = 5 does not – bash interprets X as a command with arguments = and 5.


How PATH Works

PATH is a colon-separated list of directories. When you type a command, the shell searches these directories left to right until it finds a match:

echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

When you type gcc, the shell checks each directory in order:

  1. /usr/local/sbin – not there
  2. /usr/local/bin – not there
  3. /usr/sbin – not there
  4. /usr/binfound it – runs /usr/bin/gcc

Verify where a command lives with which:

which gcc       # /usr/bin/gcc
which ls        # /usr/bin/ls

Why ./hello Is Required

The current directory (.) is not in PATH by default. This is a security feature. If . were in PATH, someone could place a malicious program named ls in a shared directory, and running ls there would execute the malicious version instead of /usr/bin/ls.

The ./ prefix explicitly tells the shell: “run the program in this directory, not from PATH.”

gcc -Wall -o hello hello.c
hello          # Command 'hello' not found
./hello        # Hello, world!

Every lab in this course requires ./programname to run your compiled executables. This is not a bug – it is Unix enforcing explicit intent.

Adding to PATH

You can prepend a directory to PATH so the shell searches it first:

export PATH="$HOME/bin:$PATH"

This adds ~/bin to the front of PATH. The shell will now check ~/bin before any system directory. The original PATH is preserved by including $PATH at the end.


Shell Startup Files: .bashrc and .profile

Anything you type at the command line disappears when you close the terminal. To make settings permanent, put them in a startup file.

Two files matter:

File When it runs
~/.bash_profile (or ~/.profile) Login shells – SSH sessions, first terminal on some systems
~/.bashrc Non-login shells – every new terminal window

On Ubuntu, ~/.bashrc is the file you edit for daily customization. If you are unsure which to use, use ~/.bashrc.

Editing .bashrc

Open it in your editor:

nano ~/.bashrc

Add lines at the bottom:

# Custom aliases
alias ll='ls -la'
alias rm='rm -i'

# Compiler defaults
export CC=gcc
export CFLAGS="-Wall -Wextra -std=c17"

# Add personal bin to PATH
export PATH="$HOME/bin:$PATH"

Save and exit. The changes take effect only after you reload the file.

Reloading with source

The source command (or its shorthand .) re-reads a file in the current shell:

source ~/.bashrc

This applies your changes immediately without opening a new terminal. You will run this command every time you modify ~/.bashrc.

. ~/.bashrc          # Same as source ~/.bashrc

Aliases

Aliases let you create shortcuts for commands you type frequently:

alias ll='ls -la'
alias compile='gcc -Wall -Wextra -std=c17 -o'
alias cls='clear'

Check your current aliases:

alias                # List all aliases
type ll              # ll is aliased to 'ls -la'

Remove an alias:

unalias ll

Aliases defined at the command line vanish when the terminal closes. To make them permanent, add them to ~/.bashrc and run source ~/.bashrc.


Viewing All Variables with env

The env command prints every environment variable in the current shell:

env

To filter for a specific variable, pipe through grep:

env | grep PATH
env | grep SHELL

Key Insight: env shows only exported environment variables. Shell-local variables (set without export) do not appear in env output. Use set to see everything, including shell-local variables.


Check Your Understanding
You add alias ll='ls -la' to ~/.bashrc and save the file, but typing ll gives "command not found." What is the most likely fix?
ARestart the computer so the new config takes effect
BRun export alias ll='ls -la' to make it visible
CRun source ~/.bashrc to reload the configuration file
DMove the alias to /etc/bashrc instead
Answer: C. Saving ~/.bashrc only writes the file to disk -- it does not re-execute it. The shell reads ~/.bashrc when a new terminal opens. To apply changes in the current terminal, run source ~/.bashrc. You do not need to restart anything.

What Comes Next

You now control your shell environment: variables configure program behavior, PATH determines which commands the shell finds, and ~/.bashrc makes your settings permanent.

In the next lesson, you will learn how the shell rewrites your commands before executing them – the expansion and quoting mechanisms that explain why echo * prints filenames instead of an asterisk, and how to control that behavior.