Working Code
Example 1: Checking environment variables
echo $HOME
Example output:
/Users/dale
echo $USER
Output:
dale
echo $PATH
Example output:
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
PATH is a list of directories separated by : (colons).
Example 2: Setting variables
# Local variable (only valid in the current shell)
MY_NAME="Alice"
echo $MY_NAME
Output:
Alice
# Environment variable (passed to child processes)
export MY_NAME="Alice"
echo $MY_NAME
When you export a variable, other programs launched from this shell can read it too.
Example 3: Viewing all environment variables
env
Output (partial):
HOME=/Users/dale
USER=dale
SHELL=/bin/zsh
PATH=/usr/local/bin:/usr/bin:/bin
LANG=ko_KR.UTF-8
...
You can filter with a pipe: env | grep PATH.
Try It Yourself
Local Variables vs. Environment Variables
# Local variable: current shell only
MY_VAR="hello"
bash -c 'echo $MY_VAR' # empty in child bash
Output:
<- empty (not accessible in child shell)
# Environment variable: passed to child processes
export MY_VAR="hello"
bash -c 'echo $MY_VAR'
Output:
hello
Key difference: variables created without export are only valid in the current shell.
Adding Directories to PATH
# Check current PATH
echo $PATH
# Add a new path at the beginning (higher priority)
export PATH="/new/install/path:$PATH"
# Verify
echo $PATH
If you install a new tool and get "command not found," add its install path to PATH.
alias: Shortening Long Commands
# Create aliases
alias ll='ls -la'
alias gs='git status'
alias ..='cd ..'
alias ...='cd ../..'
# Use them
ll
gs
# List current aliases
alias
# Remove a specific alias
unalias ll
Useful aliases for everyday work:
# Frequently visited directories
alias proj='cd ~/projects'
alias docs='cd ~/Documents'
# Git shortcuts
alias gs='git status'
alias ga='git add .'
alias gc='git commit -m'
alias gp='git push'
alias gl='git log --oneline'
# Better ls
alias ll='ls -la'
alias la='ls -a'
alias lt='ls -lth' # sort by recent modification
# Safe rm
alias rm='rm -i' # always ask for confirmation
Persisting Settings in the Shell Config File
Aliases and exports disappear when you close the terminal. To make them permanent, add them to your shell config file:
# zsh users (~/.zshrc)
nano ~/.zshrc
# bash users (~/.bashrc)
nano ~/.bashrc
Add at the bottom:
# Environment variables
export PROJECTS="$HOME/projects"
# Aliases
alias ll='ls -la'
alias gs='git status'
alias ..='cd ..'
# Functions
mkcd() {
mkdir -p "$1" && cd "$1"
}
Apply the changes:
source ~/.zshrc
Now the settings persist even when you open a new terminal.
"Why?" — Why PATH Matters
PATH is the list of directories the shell searches when you type a command. When you type node, the shell looks through PATH directories in order:
/usr/local/bin -> not found
/usr/bin -> not found
/bin -> found! -> execute
If the command isn't found:
zsh: command not found: node
Run which node to find where node is installed, then add that path to PATH.
Functions: More Complex Logic
For cases too complex for aliases, use functions:
# Create a directory and cd into it
mkcd() {
mkdir -p "$1" && cd "$1"
}
# Usage
mkcd new-project/src
# Back up a file before editing
backup_edit() {
cp "$1" "$1.bak" && nano "$1"
}
# Access arguments
greet() {
echo "Hello, $1!" # $1 = first argument
echo "Have a great day."
}
greet "Alice"
Common Mistakes
Mistake 1: Spaces around = in alias
# Wrong (spaces around =)
alias ll = 'ls -la'
# Correct
alias ll='ls -la'
Mistake 2: Forgetting to source
# After editing .zshrc, always apply it
source ~/.zshrc # or . ~/.zshrc
# Or just open a new terminal
Without source, new settings don't take effect in the current terminal.
Mistake 3: Forgetting export for child processes
# Only valid in the current shell
MYVAR="hello"
npm start # npm can't read MYVAR
# Now npm can read it
export MYVAR="hello"
npm start
Mistake 4: Committing .env files to git
# .env files contain sensitive data like API keys and passwords
DATABASE_URL=postgresql://...
API_KEY=sk-...
# Never commit these to git!
# Always add to .gitignore
echo ".env" >> .gitignore
Deep Dive
.env files and development environment variables
In development, API keys and DB passwords are stored in .env files:
# .env file
DATABASE_URL=postgresql://localhost/mydb
API_KEY=secret123
NODE_ENV=development
Loading them:
source .env
echo $DATABASE_URL
Most frameworks (Node.js, Python, etc.) read .env automatically. Always add .env to .gitignore.
Finding command locations with which and type
# Where is a command installed?
which node
# /usr/local/bin/node
which python3
# /usr/bin/python3
# Check if something is an alias or function
type ll
# ll is an alias for ls -la
type mkcd
# mkcd is a shell function
When multiple versions are installed, this shows which one runs.
Types of shell config files
| File | When it runs |
|------|-------------|
| ~/.zshrc | Interactive zsh shell startup |
| ~/.bashrc | Interactive bash shell startup |
| ~/.zshenv | Every zsh shell (including scripts) |
| ~/.bash_profile | Bash login shell startup |
On macOS with zsh, you only need to worry about ~/.zshrc.
- Check basic environment variables with
echo $HOME,echo $USER,echo $SHELL. - Set a variable with
export MYPROJECT="/tmp/test"and verify withecho $MYPROJECT. - Create an alias with
alias ll='ls -la'and use it. - Run
aliasto see all currently defined aliases. - Add 3 useful aliases to
~/.zshrc(or~/.bashrc) and apply withsource.
Q1. How do you make an environment variable available to child processes (npm, python, etc.) as well?
- A)
set VARNAME=value - B)
export VARNAME=value - C)
env VARNAME=value - D)
declare VARNAME=value