Prerequisites#
- M8 (parameter and command expansion)
- M9 (quoting — you will need it around values with spaces)
Learning objectives#
By the end of this module you will be able to:
- Set and print shell variables; tell local vs environment variables apart
- Use
export, inspect withenv/set, and customisePATHcarefully - Change
PS1for the current session to shorten or clarify your prompt - Reuse commands with
history,!!,!<n>,!<string>, and Ctrl+R - Speed up typing with Tab completion
Variables: assign, expand, export#
Assign with no spaces around =:
COURSE_LAB=linux-from-scratch
echo "COURSE_LAB=$COURSE_LAB"
COURSE_LAB=linux-from-scratch
A plain assignment is visible to the current shell. Child processes (commands you launch) see it only after export:
export COURSE_LAB
env | grep '^COURSE_LAB='
COURSE_LAB=linux-from-scratch
| Tool | What it shows |
|---|---|
echo $VAR |
One variable’s value |
set |
Shell variables and functions (large list) |
env |
Exported environment variables for child processes |
Useful built-ins you already rely on:
echo "User=$USER Home=$HOME Shell=$SHELL Pwd=$PWD"
echo "PATH first three: $(echo "$PATH" | tr ':' '\n' | head -3 | paste -sd: -)"
Example from a lab session:
PATH first three: /usr/local/bin:/usr/bin:/bin
PATH — how the shell finds commands#
PATH is a colon-separated list of directories. When you type ls, bash searches those directories in order.
Temporary experiment (this shell only):
echo "$PATH"
# Prepend a personal bin directory IF you created one:
# export PATH="$HOME/bin:$PATH"
Do not wipe PATH with PATH= unless you like repairing the session. If you break it, start a new terminal tab.
Prompt string PS1#
PS1 controls your interactive prompt. Try a short temporary prompt:
OLD_PS1="$PS1"
PS1='lab> '
# … work …
PS1="$OLD_PS1" # restore
You might see lab> instead of your usual long prompt. Closing the terminal discards the change — perfect for experiments. Permanent prompts belong in startup files (M11).
Common escapes inside PS1 (for later customising): \u user, \h host, \w working directory, \$ # for root else $.
History: stop retyping#
history | tail -n 10
| Shortcut | Meaning |
|---|---|
!! |
Re-run the previous command |
!<n> |
Re-run history event number n |
!<string> |
Re-run the most recent command starting with string |
| Ctrl+R | Incremental reverse search — type a few letters, Enter to run |
Example workflow:
ls /tmp/linux-lab-pushpjeet
# … later …
!ls # reruns the last command that began with ls
Safety: !! on a destructive command is still destructive. Glance before you press Enter — especially after sudo.
History is often stored in ~/.bash_history when the shell exits cleanly. Settings like HISTSIZE appear in M11.
Tab completion#
Type the start of a command or path, press Tab:
- One match → bash fills it in
- Several matches → Tab twice lists them
cd /tmp/linux-lab-pushpjeet/vi # press Tab → vim-lab/ if unique
Completion works for many commands’ options too (distro-dependent). Make Tab a habit; your wrists will thank you.
Local vs environment — a quick picture#
┌─ your bash session ─────────────────────┐
│ MY_LOCAL=hello (shell only) │
│ export COURSE_LAB=… (env + children) │
│ │ │
│ ▼ child process (e.g. python) │
│ sees COURSE_LAB, not MY_LOCAL │
└─────────────────────────────────────────┘
Common mistakes#
VAR = valuewith spaces — bash tries to run a command namedVAR. UseVAR=value.- Forgetting quotes on values with spaces —
NAME=Ada LovelacerunsLovelaceas a command; useNAME='Ada Lovelace'. - Exporting secrets into the environment casually — anything exported can show up in process listings. Be thoughtful on shared machines.
- Permanent
PATHedits without a backup plan — experiment in the current shell first; persist in M11 only when happy. - Blind
!!after a typo that did damage — checkhistoryfirst.
Hands-on lab#
mkdir -p /tmp/linux-lab-pushpjeet/m10-lab
cd /tmp/linux-lab-pushpjeet/m10-lab
- Set
CITY=Calcuttaand echo it. Thenexport CITYand confirm withenv | grep CITY. - Save your prompt:
OLD="$PS1", setPS1='m10> ', runpwd, restorePS1="$OLD". - Run
date, then re-run it with!!(or find it via Ctrl+R). - Type
ecand Tab-complete towardecho, then print$COURSE_LABif still set from earlier practice (or set it again).
Verify: env shows CITY; your prompt returned to normal after restore.
Practice: check your understanding#
Multiple choice#
1. Which assignment is syntactically correct in bash?
- A.
COURSE = linux - B.
COURSE=linux - C.
export =linux - D.
set COURSE linux
Answer
B. No spaces around =.
2. What does export VAR=1 do beyond a plain assignment?
- A. Writes VAR to disk forever
- B. Makes VAR available to child processes
- C. Hides VAR from
echo - D. Deletes VAR after one use
Answer
B. Exported variables enter the environment inherited by children.
3. What does !! do?
- A. Clear history
- B. Start vim
- C. Re-execute the previous command
- D. Toggle Tab completion
Answer
C. !! expands to the previous command line.
4. Which tool lists environment variables for child processes?
- A.
cat - B.
env - C.
chmod - D.
tee
Answer
B. env shows the exported environment.
5. Changing PS1 in the current terminal without editing files is:
- A. Permanent for all users
- B. Permanent for your user only
- C. Temporary until the shell exits (unless saved in a startup file)
- D. Illegal in bash
Answer
C. Session-only unless you add it to a startup file (M11).
Flashcards#
| Front | Back |
|---|---|
VAR=value |
Set shell variable (no spaces) |
export VAR |
Publish VAR to the environment |
env |
List environment variables |
PS1 |
Interactive prompt string |
PATH |
Directories searched for commands |
!! |
Previous command |
!42 |
Run history event 42 |
| Ctrl+R | Reverse history search |
| Tab | Complete command or path |
$HOME |
Your home directory path |
Fill in the blank#
- Export a variable in one step:
export COURSE=linux-from-scratch - Show history:
history | tail - Re-run last command:
!! - Temporary prompt:
PS1='lab> '
Answer key
export COURSE=linux-from-scratchhistory(optionally piped totail)!!PS1='lab> '(quotes recommended)
Mini terminal challenge#
Goal: Prove you understand export vs local.
Setup
cd /tmp/linux-lab-pushpjeet
Tasks
LOCAL_ONLY=visible-in-shell(do not export).export CHILD_SEES=visible-in-env- Run
bash -c 'echo LOCAL=$LOCAL_ONLY CHILD=$CHILD_SEES' - Explain the printed line in one sentence (LOCAL empty or unset, CHILD set).
Verify: Output looks like LOCAL= CHILD=visible-in-env (LOCAL blank).
Stretch: Use Ctrl+R to find your export line and run a harmless echo of CHILD_SEES again.
Next: M11 — Shell startup files — make aliases and exports stick across sessions.