Environment variables are named values that programs can read. They store configuration like paths, preferences, and credentials that affect how software runs.

Think of them as settings that live in your shell session.

Viewing Environment Variables

See all of them:

env

Or:

printenv

See a specific one:

echo \$HOME
echo \$PATH
echo \$USER

Common Environment Variables

Variable What it contains
HOME Your home directory (/Users/yourname)
USER Your username
PATH Folders to search for commands
SHELL Your shell (/bin/zsh)
PWD Current directory
EDITOR Default text editor
LANG Language/locale settings

Setting Environment Variables

For current session only:

export MY_VAR="some value"

Test it:

echo \$MY_VAR

This disappears when you close Terminal.

Permanently (add to ~/.zshrc):

echo 'export MY_VAR="some value"' >> ~/.zshrc
source ~/.zshrc

Now it's set in every new Terminal session.

The export Command

export makes a variable available to child processes (programs you run):

# Without export - only available in current shell
MY_VAR="hello"

# With export - available to programs you run
export MY_VAR="hello"

For environment variables, always use export.

Common Use Cases

API Keys and Secrets

Never put API keys in code. Use environment variables:

export OPENAI_API_KEY="sk-abc123..."
export DATABASE_URL="postgres://user:pass@host/db"

Your code reads them:

import os
api_key = os.environ.get('OPENAI_API_KEY')

Development Settings

export NODE_ENV="development"
export DEBUG="true"
export PORT="3000"

Tool Configuration

export EDITOR="nano"
export VISUAL="code"
export PAGER="less"

Checking If a Variable Exists

if [ -z "\$MY_VAR" ]; then
    echo "MY_VAR is not set"
else
    echo "MY_VAR is: \$MY_VAR"
fi

Or simply:

echo \${MY_VAR:-"not set"}

Unsetting Variables

Remove a variable:

unset MY_VAR

Environment Variables in Scripts

At the top of a script, you might set variables:

#!/bin/zsh

export APP_ENV="production"
export LOG_LEVEL="info"

# Rest of script uses these

Or load from a file:

source .env

The .env File Pattern

Many projects use a .env file for configuration:

# .env file
DATABASE_URL=postgres://localhost/mydb
API_KEY=abc123
DEBUG=true

Load it in your shell:

export \$(cat .env | xargs)

Important: Never commit .env files to git - they often contain secrets.

Scope and Inheritance

Environment variables flow downward:

Terminal (zsh)
  └─ export VAR="value"
       └─ Runs script.sh (VAR is available)
            └─ Script runs node app.js (VAR is available)

Child processes inherit parent's environment. They can't change the parent's environment.

Viewing One Variable

# Using echo
echo \$PATH

# Using printenv
printenv PATH

Both show the value. printenv is cleaner for scripting.

PATH is Special

PATH is the most important environment variable. It lists folders where your shell looks for commands:

echo \$PATH

Add to it:

export PATH="/new/folder:\$PATH"

Learn more in What is PATH on Mac?

Debugging

See what environment a program receives:

env | sort

Check if something is set:

echo "HOME: \$HOME"
echo "USER: \$USER"
echo "CUSTOM: \${CUSTOM_VAR:-not set}"

Keep Learning

Environment variables are how you configure your development environment. The free course covers this and other Terminal fundamentals.

Check it out at Mac Terminal for Humans.