learn.colinkim.dev

Environment variables and shell configuration

Learn how environment variables shape command behavior, how shell startup files work, and how to customize your shell with aliases, functions, and prompt changes.

This is how someone moves from terminal user to terminal power user.

Environment variables and shell configuration control how commands behave and how your terminal looks and feels.

Environment variables

An environment variable is a named value stored in your shell’s environment. Commands read these values to change their behavior.

echo $HOME           # your home directory
echo $USER           # your username
echo $SHELL          # your default shell
echo $LANG           # your locale

Setting variables

To set a variable for the current session:

MY_VAR="hello"
echo $MY_VAR         # hello

To make it available to child processes (commands you run), use export:

export MY_VAR="hello"
python -c "import os; print(os.environ.get('MY_VAR'))"    # hello

Without export, the variable exists only in the shell itself, not in programs the shell launches.

The PATH variable

PATH is the most important environment variable. It is a colon-separated list of directories where the shell looks for commands.

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

When you add a tool to your system (like Node.js or a custom script), its bin directory needs to be in PATH for you to run it by name.

To add a directory temporarily:

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

This prepends $HOME/.local/bin to the front of PATH. The change lasts only for the current session.

Shell startup files

When a shell starts, it reads configuration files. These files control your environment, aliases, prompt, and more.

The file that gets read depends on the shell and how it was started:

For zsh (macOS default):

  • ~/.zshrc — read every time an interactive shell starts
  • ~/.zprofile — read for login shells

For bash:

  • ~/.bashrc — read for interactive non-login shells
  • ~/.bash_profile or ~/.profile — read for login shells

The difference matters

On macOS, Terminal.app starts a login shell, so ~/.bash_profile or ~/.zprofile is read. If you put config in ~/.bashrc but open a login shell, it may not be loaded.

The simplest approach: for bash, source ~/.bashrc from ~/.bash_profile:

# in ~/.bash_profile
if [ -f ~/.bashrc ]; then
  source ~/.bashrc
fi

For zsh, ~/.zshrc is usually sufficient.

Aliases

An alias is a shortcut for a longer command:

alias ll="ls -la"
alias gs="git status"
alias ..="cd .."

After defining these, typing ll runs ls -la.

Aliases are convenience, not magic. They expand before the command runs:

alias ll
# ll='ls -la'

To remove an alias:

unalias ll

Shell functions

For more complex shortcuts, use functions:

mkcd() {
  mkdir -p "$1" && cd "$1"
}

Now mkcd new-project creates a directory and enters it in one step.

Functions can accept arguments ($1, $2, etc.) and run multiple commands.

Making configuration persistent

Aliases and functions defined at the prompt last only for the current session. To make them permanent, add them to your startup file:

# in ~/.zshrc or ~/.bashrc
alias ll="ls -la"
alias gs="git status"

mkcd() {
  mkdir -p "$1" && cd "$1"
}

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

After editing the file, reload your shell:

source ~/.zshrc    # or source ~/.bashrc

Prompt customization

Your shell prompt is controlled by a variable — PS1 in bash, PROMPT in zsh.

# bash: simple prompt
export PS1="$ "

# bash: show current directory
export PS1="[\w]$ "

# zsh: show current directory
PROMPT="%~$ "

Most people use a framework like Starship or Oh My Zsh for prompt customization rather than writing prompt strings by hand.

Viewing all environment variables

env                # print all environment variables
printenv           # same
printenv PATH      # print just one variable

Must understand

These concepts are foundational:

  • Environment variables shape command behavior. Tools read them to know your home directory, language, preferred editor, and more.
  • Startup files control shell behavior. Your aliases, functions, PATH modifications, and prompt settings live here.
  • Aliases are convenience, not magic. They are simple text substitutions defined in your current session or startup file.
  • PATH changes what programs are found. If a command says “not found,” it is either not installed or not in your PATH.

The main idea to carry forward

Environment variables and startup files are the mechanism by which your shell remembers preferences. export makes variables available to child processes. Startup files (~/.zshrc, ~/.bashrc, etc.) are where persistent configuration lives. Aliases and functions are shortcuts you define once and use forever.

Progress

Quick checks

No quick checks in this lesson.

Mark lesson manually or answer quick checks to track progress.