Environment Variables Basics - Configuration and Practical Usage
What you'll be able to do
- Check what an environment variable holds with `echo $VAR` or `env`
- Set one with `export`, and explain how it differs from a shell variable
- Understand how `PATH` works and fix `command not found` on your own
Prerequisites (read these first)
What You'll Learn
- Check environment variableA named value that the shell or a program can look up while running. values with
echo $VARorenv - Define your own environment variables with
export - Understand
PATHand fix "command not found" errors on your own - Persist settings across sessions using
.bashrc
Target Audience: You know basic commands (pwd, cd, ls) but feel uncertain about what $HOME or export actually means.
Introduction: What Are Environment Variables?
$HOME and $PATH in tutorials. What are those? The $ sign feels like a magic spell./home/lina" under the name HOME. Write $HOME and it hands you the value.Words used here
- Variable: a named box that holds a value. Write the name and you get the contents.
- Shell variable: a variable that exists only inside the current shell.
- Environment variable: a shell variable that is also handed to commands you start from there.
exportis what makes it one. - Child process: a command started from another command.
So an environment variable is a shell variable with a "pass this along" mark on it. Section 2 proves the difference with an experiment.
Quick Summary
- Just check a value →
echo $VARorenv | grep VAR - Use it only in your current shell →
export VAR=value - Keep it for next login → write it in
~/.bashrc - 80% of "command not found" errors are PATHA string that describes the location of a file or directory.-related
Prerequisites
- OS: Ubuntu / other Linux distributions
- Shell: bash (zsh works almost the same)
- A terminal showing the
$promptA symbol (like $ or #) shown when the shell is waiting for your input.
1. Reading Environment Variables
Conclusion: Read one with
echo $VARand all withenvfirst.
1-1. Show one variable: echo $VAR
$ echo $HOME
/home/lina
$ echo $USER
lina
Key Points
$means "replace this with the variable's value". That replacement is called expansion.- Without
$,echo HOMEjust prints the plain text "HOME". - Variable names are uppercase by convention. It is not required, but keeping to it makes files easier to read.
$ makes a huge difference.$ is the switch that pulls out the value".1-2. Show all variables: env / printenv
$ env
SHELL=/bin/bash USER=lina HOME=/home/lina PATH=/usr/local/bin:/usr/bin:/bin LANG=en_US.UTF-8 PWD=/home/lina ...
env lists every environment variable you currently have. printenv does the same job.
If the output is long, use env | less to read it one screen at a time. To find one variable, filter with env | grep PATH.
1-3. Common variables to know
| Variable | Meaning | Example |
|---|---|---|
HOME |
Your home directory | /home/lina |
USER |
Current username | lina |
PATH |
Directories searched for commands | /usr/local/bin:/usr/bin:/bin |
SHELL |
Your login shellThe first shell started right after a user logs in. | /bin/bash |
LANG |
Language and locale | en_US.UTF-8 |
PWD |
Current directory (same as pwd) |
/home/lina/work |
HOME and PATH really matter. For the rest, "good to know it exists" is enough.2. Setting Variables: Assignment vs export
Conclusion: A plain assignment stays in the current shell. export makes it an environment variable that children inherit.
2-1. Plain assignment (shell variable)
$ MY_NAME=lina $ echo $MY_NAME
lina
Put no spaces around =.
Write MY_NAME = lina and the shell reads it as "run a command called MY_NAME". That fails. It is the most common beginner accident.
2-2. Promote to "environment variable" with export
$ MY_NAME=lina $ export MY_NAME
Or in one shot:
$ export MY_NAME=lina
export? They look the same to me.export and it becomes an environment variable that children can read.2-3. See the difference yourself
$ MY_VAR=hello $ bash -c 'echo $MY_VAR'
Nothing is printed; you get a blank line. bash -c starts a new shell as a child process, and MY_VAR never reached it.
$ export MY_VAR=hello $ bash -c 'echo $MY_VAR'
hello
This time it printed. The export handed the value down to the child.
Rule of thumb: If a script or another command needs the value, always use export. For a personal scratchpad, plain = is fine.
2-4. Delete a variable
$ unset MY_VAR $ echo $MY_VAR
unset removes the variable from the current shell only.
A value written in .bashrc stays until you edit that file.
3. PATH: The Most Important Variable
Conclusion: PATH is the list of directories searched for commands. Always keep :$PATH at the end when you add one.
PATH and you can fix "command not found" yourself.3-1. Inspect PATH
$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
Key Points
PATHholds a list of directories, separated by:.- When you type a command, the shell searches those directories left to right.
- The first command with a matching name wins.
Think of a row of school lockers. PATH is the instruction that says which row to check first.
3-2. Find where a command lives: which
$ which ls
/usr/bin/ls
$ which python3
/usr/bin/python3
ls actually lives in /usr/bin/.ls works because /usr/bin is in your PATH.PATH and you would have to type the full path, /usr/bin/ls, every time.3-3. Add a personal directory to PATH
Suppose you want a ~/bin folder for your own scripts.
$ mkdir -p ~/bin $ export PATH="$HOME/bin:$PATH"
Always keep :$PATH at the end.
Writing export PATH="$HOME/bin" alone wipes out the existing PATH. Almost every command then reports "command not found". It is the most frequent accident with this variable.
If it happens, opening a new terminal restores it. As long as you did not write it into a config file, nothing else is needed.
3-4. Order changes behavior
# Prefer my own version $ export PATH="$HOME/bin:$PATH" # Prefer the system version (mine as fallback) $ export PATH="$PATH:$HOME/bin"
Handy tip: When a PATH change breaks something, run which command-name. It shows exactly which file is being picked up, which is the fastest route to the cause.
3-5. Lina gets stuck: overwriting PATH
export PATH="$HOME/bin" and now neither ls nor cat works. Did I break my machine?PATH, so the shell stopped looking in /usr/bin..bashrc, that is the whole repair.Fixing it without a new terminal
If you would rather fix the shell you are in, type this:
$ export PATH="/usr/local/bin:/usr/bin:/bin:$PATH"
The basic commands work again. Then rewrite the line properly.
4. Persistence: Surviving the Next Login
Conclusion: export lasts only for the current shell. To keep a value, write it in ~/.bashrc and apply it with source.
export. When I closed the terminal, it was gone.export lives for the current shell only.First, the way back
From here on you edit a config file. A mistake in one can print an error every time you open a terminal.
Copy it before you edit.
$ cp ~/.bashrc ~/.bashrc.bak
If something goes wrong, restore the copy.
$ cp ~/.bashrc.bak ~/.bashrc $ source ~/.bashrc
If the terminal opens and closes immediately, start a shell that skips the settings files. From another terminal, type bash --norc --noprofile, then run the cp above.
4-1. Which file should I edit?
| File | When it loads | Typical use |
|---|---|---|
~/.bashrc |
Every interactive bash shell | Personal vars and aliases |
~/.profile / ~/.bash_profile |
Once at login | Env vars on SSH login |
/etc/environment |
System-wide, all users | Shared system settings (rootThe special administrator account allowed to do anything on the system.) |
When in doubt, edit ~/.bashrc. It's the most reliable choice for GUI terminals, WSL, and SSH sessions.
4-2. Example .bashrc additions
Append to the bottom:
# Personal scripts directory export PATH="$HOME/bin:$PATH" # Locale export LANG=en_US.UTF-8 # Default editor export EDITOR=vim
4-3. Reload immediately with source
$ source ~/.bashrc
Or the dot shortcut:
$ . ~/.bashrc
Many people forget source and then wonder why PATH has not changed.
After editing a config file, always run source. Logging in again has the same effect.
source actually do?export inside it never comes back to the parent shell.source runs the lines in the shell you are in, so the settings stay.5. Common Pitfalls
Conclusion: A missing $, spaces around =, an overwritten PATH, and the wrong quotes. Those four are the classic accidents.
5-1. Forgetting / adding $
# Wrong: prints the literal string "HOME" $ echo HOME # Right: expands the value $ echo $HOME
5-2. Spaces around =
# Wrong: parsed as a command, fails $ MY_VAR = hello # Right $ MY_VAR=hello
5-3. Wiping out PATH
# Disaster: existing PATH is gone $ export PATH="$HOME/bin" # Correct $ export PATH="$HOME/bin:$PATH"
If you accidentally wipe PATH, just open a new terminal. The default comes back on its own. There is no need to edit .bashrc in a panic.
5-4. Single vs double quotes
$ NAME=lina # Double quotes: $NAME is expanded $ echo "Hello $NAME"
Hello lina
# Single quotes: literal, no expansion $ echo 'Hello $NAME'
Hello $NAME
Rule of thumb: Use double quotes "..." when you want variable expansion. Use single quotes '...' for literal strings.
5-5. "I exported it but my script doesn't see it"
When you run a script as ./script.sh, variables you exported in the parent shell are inherited.
A brand-new terminal is different. It reads .bashrc from scratch, so a variable that is not written there is gone.
For variables your scripts depend on, write them into .bashrc so they are always present.
6. Hands-On Practice
Conclusion: Print a variable, add ~/bin to PATH, run your own command. Three exercises take you from setting to persisting.
Exercise 1: Put your name in a variable and print it in the form "Hello, name".
Show Hint 1 (Direction)
First put the name in a box. Then print the contents of that box as part of a sentence. Wrap the whole sentence in quotes.
Show Hint 2 (Command name)
Assignment looks like NAME=value. Printing uses echo. Since you want the value expanded, use double quotes "...".
Show Answer
$ MY_NAME=lina $ echo "Hello, $MY_NAME!"
Hello, lina!
Replace lina with your own name. Put no spaces around the =.
Exercise 2: Create a ~/bin directory and make it part of PATH in the next terminal too.
Show Hint 1 (Direction)
Create the directory. Then append one line to the config file that adds it to PATH. Finally re-read that config file.
Show Hint 2 (Command name)
Create with mkdir -p. Append with echo and >>. Re-read with source. The file is ~/.bashrc.
Show Answer
$ mkdir -p ~/bin $ echo 'export PATH="$HOME/bin:$PATH"' >> ~/.bashrc $ source ~/.bashrc $ echo $PATH
/home/lina/bin:/usr/local/bin:/usr/bin:/bin
Seeing /home/yourname/bin near the front means it worked.
The single quotes matter here. They stop the expansion while writing to .bashrc, so it happens when the file is read instead.
Exercise 3: Put your own command in ~/bin and call it from anywhere.
Show Hint 1 (Direction)
Three steps. Create the file, mark it as runnable, then call it by name alone.
Show Hint 2 (Command name)
Create the file with cat > filename. Press Ctrl+D when you finish typing the contents. Mark it runnable with chmod +x. After that, the file name is the command.
Show Answer
$ cat > ~/bin/hello #!/bin/bash echo "Hello from my own script!"
Type those two lines, then press Ctrl+D. That saves the file.
The first line, #!/bin/bash, is the standard way to say "run this file with bash". It is called a shebang.
$ chmod +x ~/bin/hello $ hello
Hello from my own script!
If you get command not found, check that you ran source ~/.bashrc in Exercise 2.
To delete the file, run rm ~/bin/hello. A file removed with rm does not go to a trash can; it is gone at once. Check the contents with ls ~/bin before you remove anything.
PATH. "Command not found" will not scare you anymore.7. Review
$ is the switch that pulls out a value. export hands it to child processes..bashrc keeps it for the next terminal.PATH is the list of places to search. When I see command not found, I check echo $PATH and which first.:$PATH at the end when you edit it.8. Summary
Copy-paste cheat sheet
# Inspect echo $HOME # Single variable env # All variables env | grep PATH # Filter which commandname # Where does it live? # Set MY_VAR=value # Shell variable (current shell only) export MY_VAR=value # Environment variable (children too) unset MY_VAR # Delete # Add to PATH safely export PATH="$HOME/bin:$PATH" # Always append $PATH # Persist vim ~/.bashrc # Append export lines source ~/.bashrc # Apply now
Don't do this
export PATH="$HOME/bin"(wipes the existing PATH)MY_VAR = value(spaces around=)- Wrapping
$HOMEin single quotes and wondering why it isn't expanded - Editing
.bashrcwithoutsource-ing it and complaining "nothing changed"
Today's 3-Line Summary
$VARpulls out a variable's value. Read the current state withecho $HOMEorenv- Only variables marked with
exportare handed to child processes - When you add to
PATH, always keep:$PATHat the end