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.