Processes and the environment
Understand environment variables and PATH, subshells, background jobs, and signals.
- Tell shell variables from environment variables, and use export and PATH
- Predict what a subshell or child process can and can’t change
- Run jobs in the background, wait for them, and handle signals with trap
Every command you run is a process with an ID (a PID). When the shell starts a program, the program is a child, and it gets a copy of the parent’s environment - a set of NAME=value strings such as HOME, USER, LANG and PATH.
- A plain assignment,
mode=orbit, makes a shell variable: children don’t see it. export mode(orexport mode=orbit) puts it in the environment, so every child from then on gets a copy.MODE=test ./run.shsets a variable for that one command only.- A child can never change its parent’s variables - it only has a copy. That’s why a script can’t
cdfor you; yousourceit instead.
1mode="orbit"
2bash -c 'echo "child sees mode=[$mode]"'
3export mode
4bash -c 'echo "after export: mode=[$mode]"'
5GREETING="hi" bash -c 'echo "one-off: $GREETING"'
6echo "parent still has GREETING=[${GREETING:-}]"
7bash -c 'mode="changed"; echo "child set mode=$mode"'
8echo "parent mode=$mode"child sees mode=[] after export: mode=[orbit] one-off: hi parent still has GREETING=[] child set mode=changed parent mode=orbit
PATH: how the shell finds commands
When you type grep, the shell checks, in order: aliases, functions, built-ins, then each directory listed in PATH (colon-separated) until it finds an executable named grep. type -a grep shows every match; command -v grep prints the one that wins.
To add your own tools, put them in a directory such as ~/bin and add it in ~/.bashrc:
export PATH="$HOME/bin:$PATH"~/.bashrc runs for every new interactive shell - a good place for PATH, aliases (alias ll="ls -lah") and your prompt. Login shells (like an SSH session) read ~/.bash_profile first, which usually just sources ~/.bashrc. Run source ~/.bashrc to apply changes without opening a new terminal.
Try it
Does it stick?
Each line runs in your interactive shell. Decide whether it changes your current shell afterwards, or only affects a child process that disappears.
“cd /var/log”
“( cd /var/log && ls )”
“bash setup.sh (setup.sh sets PROJECT=kestrel)”
“source setup.sh (setup.sh sets PROJECT=kestrel)”
“export EDITOR=vim”
“EDITOR=nano git commit”
“files=$(cd /tmp && ls)”
Jobs: running things in the background
command &starts a command in the background and gives you the prompt back.$!holds its PID.waitpauses until background jobs finish (wait $pidfor one).jobslists your shell’s jobs;fgbrings one to the foreground; Ctrl+Z suspends the foreground job andbgresumes it in the background.ps auxorps -eflists every process;pgrep namefinds PIDs by name. The shell’s own PID is in$$.
1cd "$(mktemp -d)"
2scan() { sleep "$2"; echo "deck $1 clear" > "scan-$1.txt"; }
3start=$SECONDS
4scan 1 1 &
5scan 2 1 &
6scan 3 1 &
7wait # until all three are done
8cat scan-*.txt
9(( SECONDS - start < 3 )) && echo "the three 1-second scans overlapped: well under 3s"deck 1 clear deck 2 clear deck 3 clear the three 1-second scans overlapped: well under 3s
Signals and trap
A signal is a tiny message to a process. The common ones:
| Signal | Sent by | Default effect |
|---|---|---|
SIGINT (2) | Ctrl+C | stop |
SIGTERM (15) | kill PID | stop politely - the program can clean up first |
SIGKILL (9) | kill -9 PID | stop immediately; can’t be caught (a last resort) |
SIGTSTP | Ctrl+Z | pause |
trap 'commands' SIGNALS runs your code when a signal arrives. The pseudo-signal EXIT fires whenever the script ends, for any reason - the perfect place to clean up. A process killed by a signal exits with status 128 + the signal number, so Ctrl+C shows up as 130.
1trap 'echo "caught SIGTERM, saving state..."' TERM
2trap 'echo "goodbye from the EXIT trap"' EXIT
3echo "working..."
4kill -TERM $BASHPID # send ourselves a polite stop request
5echo "still running, because we handled it"
6sleep 5 & sleeper=$!
7kill "$sleeper"
8wait "$sleeper"
9echo "the sleeper exited with $? (128 + 15)"working... caught SIGTERM, saving state... still running, because we handled it the sleeper exited with 143 (128 + 15) goodbye from the EXIT trap
Key takeaways
Children get a copy of exported variables; nothing a child does changes its parent.
PATHdecides where commands are found; set it (and aliases) in~/.bashrc.&runs in the background,$!is its PID, andwaitwaits for it.killsends signals;traphandles them, andtrap ... EXITruns cleanup however the script ends.
Lesson quiz
7 questions · pass with 5 correct · up to 50 XP
Passing this quiz completes the lesson and keeps your streak going. Questions you miss come back in review sessions later.
Practice: write Bash scripts
Write a script in the editor and run it for real against sample input. Each run gets a fresh Linux sandbox with Bash 5.2 and the GNU tools on Wandbox, a free public service - so experiment freely, even with rm. Your script and test input are sent there.
What the child sees
The starter defines launch, which starts a child Bash that prints the MODE and PILOT environment variables. Make the script print:
mode=unset pilot=unset
mode=orbit pilot=unset
mode=orbit pilot=Adaby setting MODE=orbit without exporting it before the first call, exporting it before the second, and passing PILOT=Ada only to the third call.
- Three launches
Your script runs with Bash 5.2 and GNU tools on Wandbox, a free public service, in a fresh sandbox each time. Your script and test input are sent to that service.
Parallel deck scans
The starter scans four decks one after another, and each scan takes a second. Run all four scans in the background at the same time, wait for them, then print the results in deck order and All decks scanned. The test fails if the script takes 3 seconds or more.
- Scans in parallel
Your script runs with Bash 5.2 and GNU tools on Wandbox, a free public service, in a fresh sandbox each time. Your script and test input are sent to that service.
Questions about this lesson
Stuck? Ask. Figured something out? Share it. Explaining is one of the best ways to learn.
Loading posts…