Environment Variables
By the end of this lesson you'll understand how the shell stores values, the difference between a shell variable and an environment variable, how PATH lets you run commands by name, and how to make your settings persist across every terminal session.
Learn Environment Variables in our free Command Line course — an interactive lesson with worked examples, a practice exercise and a quick reference.
Part of the free Cli course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
What You'll Learn
1. Shell Variables vs Environment Variables
A plain assignment name=value creates a shell variable that only the current shell can see. To let a program you launch — a child process — inherit it, you must export it into the environment . That single distinction explains most "why can't my program see my variable?" confusion.
2. Reading and Inspecting Variables
Expand a value with $VAR or ${ VAR } — use the braces when the name touches other text. To list the whole environment use env (or printenv with no argument); to read one variable use printenv NAME . Note that printenv only sees exported variables, while echo $VAR expands any shell variable.
3. PATH: How the Shell Finds Commands
PATH is a colon-separated list of directories. When you type ls , the shell walks PATH left to right and runs the first ls it finds. To add your own folder, prepend it and keep the old value on the end with :$PATH — overwriting PATH entirely is how people accidentally make every command "not found".
4. The Exit Status: $?
The special variable $? holds the exit status of the command that just finished. By convention 0 means success and any non-zero value means a failure. Scripts lean on this constantly — it's how if decides whether the previous command worked.
5. Removing Variables with unset
When you no longer need a variable — especially a secret like an API token — remove it with unset . After unsetting, expanding the name gives an empty string because the variable simply no longer exists.
6. Persisting Variables Across Sessions
Anything you set in a shell vanishes when that shell closes. To load a variable every session, add the export line to a startup file. The right file depends on your shell and session type: ~/.bashrc for interactive non-login bash, ~/.bash_profile for login bash, and ~/.zshrc for zsh (the default on modern macOS). Use source to apply changes without opening a new terminal.
🎯 Your Turn: export to a child process
Fill in the one blank marked ___ using the # 👉 hint so the child bash can see the variable, then run it and check the Output panel matches.
🎯 Your Turn: extend PATH safely
Add a new folder to the front of PATH while keeping everything that was already there. Fill in the blank, then run it.
Pro Tips
- 💡 Convention: environment variable names are written in UPPER_CASE (like PATH , HOME ), while temporary script variables are usually lower-case. This makes exported settings easy to spot.
- 💡 Set a variable for just one command by prefixing it: DEBUG=1 ./run.sh sets DEBUG only for that single run, leaving your shell untouched.
- 💡 source ~/.bashrc (or the shortcut . ~/.bashrc ) reloads your startup file into the current shell — no need to close and reopen the terminal.
- 💡 Never echo secrets into the environment in shared logs. Use unset to clear tokens when you're done, and prefer per-command assignment for sensitive values.
Common Errors (and the fix)
- My program can't see my variable — you set it but never export ed it. Only exported (environment) variables are inherited by child processes.
- Every command is suddenly "not found" — you overwrote PATH instead of appending. Fix the current shell with export PATH="/usr/local/bin:/usr/bin:/bin:$PATH" and use :$PATH next time.
- "command not found" right after name = value — you put spaces around = . Assignment needs no spaces: name=value .
- $file_backup is empty — the shell looked for a variable literally named file_backup . Use braces: ${ file } _backup .
- My export vanished after closing the terminal — it was only in that shell. Add the line to ~/.bashrc or ~/.zshrc to load it every session.
📋 Quick Reference
Task
Command
Notes
Set shell variable
name="value"
No spaces around =
Export to environment
export name
Children inherit it
Read value
$name / ${ name }
Braces near other text
List all
env
printenv also works
Read one
printenv NAME
Exported vars only
Command search path
$PATH
Colon-separated dirs
Extend PATH
export PATH="dir:$PATH"
Keep old value
Last exit status
$?
0 = success
Remove variable
unset name
Deletes it
Persist a variable
echo 'export X=1' >> ~/.bashrc
Loads each session
Frequently Asked Questions
Mini-Challenge: an environment report
No blanks this time — just a brief and an outline. Combine export, $?, PATH inspection, and unset into a few commands that demonstrate everything from this lesson, and check your output against the hints in the comments.
🎉 Lesson Complete!
- ✅ A plain assignment is a shell variable; export makes it an environment variable children inherit
- ✅ Read values with $VAR / ${ VAR } ; list with env ; read one with printenv NAME
- ✅ PATH is a colon-separated list the shell searches for commands — extend it with :$PATH
- ✅ $? holds the last exit status; unset removes a variable
- ✅ Persist variables by adding export lines to ~/.bashrc , ~/.bash_profile , or ~/.zshrc
- ✅ Next lesson: Globbing and Wildcards — match many files at once with * , ? , and brace expansion
Practice quiz
How do you read the value of an environment variable named HOME?
- $HOME
- &HOME
- @HOME
- *HOME
Answer: $HOME. Prefix the name with a dollar sign: $HOME (or ${HOME}).
Which command marks a shell variable so child processes can see it?
- set
- local
- export
- env
Answer: export. export promotes a shell variable into the environment so child processes inherit it.
What does the PATH variable hold?
- The current user name
- A colon-separated list of directories searched for commands
- The shell prompt string
- Your home directory
Answer: A colon-separated list of directories searched for commands. PATH is a colon-separated list of directories the shell searches to find executables.
Which command prints ALL current environment variables?
- echo
- printf
- list
- env
Answer: env. env (or printenv with no argument) prints every variable in the environment.
What does $? contain after a command finishes?
- The exit status of the last command
- The process ID
- The current directory
- The shell name
Answer: The exit status of the last command. $? holds the exit status of the most recent command: 0 means success, non-zero means failure.
What is the difference between a shell variable and an environment variable?
- Shell variables are numbers, environment variables are text
- A shell variable is local to the current shell until you export it into the environment
- Environment variables cannot be changed
- There is none
Answer: A shell variable is local to the current shell until you export it into the environment. A plain assignment makes a shell variable; export turns it into an environment variable inherited by child processes.
Which command removes a variable entirely?
- delete VAR
- rm VAR
- clear VAR
- unset VAR
Answer: unset VAR. unset VAR removes the variable from the shell and environment.
Why use printenv HOME instead of echo $HOME in scripts?
- echo cannot read variables
- There is no difference at all
- printenv only prints variables that are actually exported in the environment
- printenv is faster
Answer: printenv only prints variables that are actually exported in the environment. printenv reads the environment directly, so it shows nothing for an unexported shell variable, while echo $HOME expands any shell variable.
Which file is read for each new interactive non-login bash shell, such as a new terminal tab on Linux?
- ~/.bash_profile
- ~/.bashrc
- /etc/shadow
- ~/.ssh/config
Answer: ~/.bashrc. ~/.bashrc runs for interactive non-login shells; .bash_profile runs for login shells.
How do you make a variable persist across all future terminal sessions?
- Add the export line to a startup file like ~/.bashrc or ~/.zshrc
- Run set -x
- Save it with the save command
- Type export once in the current shell
Answer: Add the export line to a startup file like ~/.bashrc or ~/.zshrc. Variables set in the current shell vanish when it closes; add the export line to a startup file to load it every session.
Continue this course
- Previous: Permissions and Users
- Next: Globbing and Wildcards