Learn › Linux Foundations › Chaining
&& - a hands-on Linux lab on a real virtual machine.
Every command leaves an exit code, and && reads it. Learn the success gate by doing: read exit codes with $?, watch the blind semicolon run past a failure, open the && gate, gate real work, stack gates, and preview the guard line, right in the practice terminal.
You are at a Linux prompt with a small workspace already laid out for you. There is a file that really exists, present.txt, and a name that points at nothing, missing.txt.
Here is the puzzle. You want to run a second command, but ONLY when the first one actually worked. Make a backup, and only if it succeeds, delete the original. Update the code, and only if that succeeds, restart the server. One wrong move on a real machine and you have deleted a file you never backed up.
By the end of this lesson you will have a single character pair, &&, that does exactly this: it runs the next command only when the previous one succeeded. And you will understand the tiny signal every command leaves behind that makes it possible.
The black boxes below are a practice terminal: a safe sandbox that checks only the one command each step teaches, so nothing you type can break anything. At the end you launch a real Linux machine and run the whole thing there.
Every command, when it finishes, leaves behind one number called its exit code. It is the command's way of reporting whether it worked. The rule never changes: 0 means success, and any other number means failure. Exit codes and the deeper story behind them get their own full lessons later in this module. Right now you need just enough to see what && reads.
Two tiny built-in commands exist just to demonstrate this. true does nothing at all except succeed. false does nothing except fail. To read the exit code of the command you just ran, you print the special variable $?, which always holds the exit code of the most recent command.
You will join the two commands with ;, the connector from the semicolon lesson: run this, then that. Before you run the line, decide: true succeeds, so which number should $? show?
prompt: student@linuxcamp:~$ answer: true; echo $? output: 0 hint: Type it exactly, semicolon and all: true; echo $?
true succeeded, so the exit code it left behind is 0. The $? you printed is Linux's built-in memory of that one number. You did not see true itself print anything, because its entire job is to quietly succeed.
Now the opposite. false always fails. Before you press Enter, decide: will the number be 0 again, or something else?
prompt: student@linuxcamp:~$ answer: false; echo $? output: 1 hint: Same shape as before, just false this time: false; echo $?
1, not 0. That is failure. This is the whole vocabulary of chaining in two words: true leaves 0 (success), false leaves 1 (failure). Real commands do the same thing, quietly, every single time they run. && is about to read that number for you.
One quirk worth knowing early: $? remembers only the LAST command. If you print it twice in a row, the second read reports the exit code of the first echo, which succeeded, so it shows 0. The signal is always fresh, never stale.
Remember from the semicolon lesson: ; runs this, then that, and never checks how the first command went. That blindness is exactly the danger in the backup-then-delete puzzle. Refresh it with one line. Before you run it, decide: false fails, so does still-runs print or not?
prompt: student@linuxcamp:~$ answer: false; echo still-runs output: still-runs hint: false fails, but the semicolon runs the echo regardless: false; echo still-runs
false failed, and echo still-runs ran anyway. That is the danger. "Back up, then delete" written with a semicolon will delete even when the backup failed. You need a connector that checks first. That is the whole reason && exists.
Here it is. The and-operator && between two commands means "run the second one ONLY if the first one succeeded." It reads that exit-code signal for you and decides.
First the success case. true succeeds, so whatever follows && should run:
prompt: student@linuxcamp:~$ answer: true && echo ran output: ran hint: Two ampersands between the commands: true && echo ran
ran printed, because true handed && a success. Compare this to the semicolon: ; would have printed ran no matter what. && printed it because, and only because, the first command worked.
Now the case that makes && worth learning. Put false first. It fails, so && should skip the second command entirely, leaving no output at all:
prompt: student@linuxcamp:~$ answer: false && echo skipped output: hint: false fails first, so the echo never runs and nothing prints: false && echo skipped
Nothing printed. That blank result is the entire point. false failed, && read the failure, and the echo never happened. This is exactly what "delete only if the backup worked" needs: when the first step fails, the dangerous second step is skipped.
Line up the two behaviors: false; echo x prints x (the semicolon ignores failure), but false && echo x prints nothing (the and-operator respects it). Same two commands, one character of difference, opposite safety.
true and false were training wheels. Real commands leave the same signal. ls present.txt lists a file that exists, so it succeeds; whatever follows && then runs:
prompt: student@linuxcamp:~$ answer: ls present.txt && echo found output: present.txt found hint: ls the file that exists, then && the echo: ls present.txt && echo found
Two lines: ls printed the filename it found, then, because that succeeded, && let echo found run. If you had pointed ls at missing.txt instead, it would fail, and found would never appear. Success gates the chain.
This is the pattern behind commands you will type for years: mkdir project && cd project, or apt-get update && apt-get install thing. Each && is a safety gate: only go on if the last step actually worked. Gates stack, too. In a && b && c, the chain only reaches c when both earlier steps succeeded. One failure anywhere and the chain stops right there.
&& has a mirror twin worth one sentence before your recap: the or-operator || runs the next command ONLY if the first one FAILED. It gets its own full lesson next. You need just the idea here, because together the two make the classic guard line: command && do-this-on-success || do-that-on-failure. The first outcome decides which branch prints.
This is the whole idea as one fork. The command runs and leaves an exit code; 0 sends control down the && branch, any non-zero sends it down the || branch. Flip the switch below to make the command succeed or fail, and watch the live exit code and the lit branch change:
{ "caption": "cmd && echo worked || echo failed: exit 0 takes the && branch, any non-zero takes the || branch.", "command": "cmd", "start": "success", "success": { "op": "&&", "label": "echo worked", "result": "worked" }, "failure": { "op": "||", "label": "echo failed", "result": "failed" } }
Start with the success path. true succeeds, so the && branch runs and the || branch is skipped:
prompt: student@linuxcamp:~$ answer: true && echo worked || echo failed output: worked hint: true, then the && branch, then the || branch: true && echo worked || echo failed
Only worked printed. true triggered the && side; because that side then succeeded, the || side had no failure to catch. Now swap true for false. Before you run it, decide which single word will print this time:
prompt: student@linuxcamp:~$ answer: false && echo worked || echo failed output: failed hint: same chain, false this time, so the || branch prints: false && echo worked || echo failed
Only failed printed. false failed, so the && branch was skipped, and || stepped in with the fallback. One line: try this, then announce success or announce failure. That is the milestone. The && gate is yours, and the or-operator lesson next door hands you the other half of this line.
Three challenges. No command is shown this time, only the goal. Everything you need is &&, the exit-code read, and commands you have already used in this lesson.
Challenge 1. In one line, run the command that always succeeds, then print the exit code it left behind.
prompt: student@linuxcamp:~$ answer: true; echo $? output: 0 hint: The always-succeeds command, the blind connector, then echo the variable that remembers the last exit code.
Challenge 2. In one line, list present.txt and print found only if the listing actually worked.
prompt: student@linuxcamp:~$ answer: ls present.txt && echo found output: present.txt found hint: List the file, then the operator that only continues on success, then the echo.
Challenge 3. Build a chain of two guaranteed successes that ends by printing all-good. If any link failed, nothing would print.
prompt: student@linuxcamp:~$ answer: true && true && echo all-good output: all-good hint: The always-succeeds command twice, with a gate after each one, then the echo. Two operators, one line.
All three from memory, with nothing to copy. The and-operator is yours.
You earned this cheat sheet. Every row is something you just ran in the practice terminal.
The one idea under all of it: every command leaves an exit code, and && reads it to decide what happens next. ; never checks, and && continues only on success. The or-operator ||, grouping with ( ) and { }, and the deeper story of exit codes each get their own lesson later in this module.
When a chain surprises you and stops early, the first thing to check is the exit code of the step before it: run the first command alone, then echo $?. A non-zero number tells you exactly why && refused to go on.
You built the and-operator toolkit yourself in the practice terminal. You read exit codes with $? and refreshed the blind semicolon. You opened the && gate on success, watched it slam shut on failure, gated real work, and stacked gates. Then you rebuilt the key moves from nothing but the goal.
Next in this module: the or-operator ||, grouping with ( ) and { }, and the exit-code lessons that deepen what you saw here. The module ends with one real Linux machine, the chaining mission lab. There you run these moves on a live workspace, and it only tests the operators these lessons teach, nothing new. The mission shows no commands. You read each objective, recall the operator, and type it, exactly the recall you just practiced here.
When you reach the chaining mission, you will chain for real.
Practice Chaining Commands with && in a real Linux terminal at The Linux Camp. Progress is verified automatically as you type commands on the machine.