Pipes and Chaining Commands
In this page:
Connecting Two Commands
The pipe operator | takes the stdout of the command on its left and feeds it as stdin to the command on its right. You can chain as many commands as you like this way.
Example: Connecting Two Commands
#!/bin/bash
printf "banana\napple\ncherry\n" | sort
Login to try C/C++/Java/PHP code in the editor
Pipelines and Exit Status
By default, the exit status of a pipeline is the exit status of its last command, regardless of whether earlier commands failed. Enabling pipefail changes this so the pipeline fails if any stage fails.
Warning: Without pipefail, a broken first stage in a long pipeline can silently be ignored.
Example: Pipelines and Exit Status
#!/bin/bash
false | true
echo "default pipeline status: $?"
set -o pipefail
false | true
echo "pipefail status: $?"
set +o pipefail
Login to try C/C++/Java/PHP code in the editor
Chaining with && and ||
&& runs the next command only if the previous one succeeded (exit status 0); || runs the next command only if the previous one failed (non-zero exit status). These are used constantly for lightweight conditional logic.
Example: Chaining with && and ||
#!/bin/bash
mkdir -p demo_dir && echo "directory ready"
rmdir demo_dir || echo "could not remove"
false || echo "this runs because the previous command failed"
true && echo "this runs because the previous command succeeded"
Login to try C/C++/Java/PHP code in the editor
Building a Small Pipeline
Real scripts often chain several small, single-purpose tools together instead of writing one big command, which mirrors the Unix philosophy of composing simple programs.
Example: Building a Small Pipeline
#!/bin/bash
printf "3\n1\n2\n1\n3\n1\n" | sort -n | uniq -c
Login to try C/C++/Java/PHP code in the editor
- Thinking a pipeline runs commands one after another; every command in a pipeline actually starts at the same time and streams data between them.
- Checking
$?after a pipeline and assuming it reflects the first command's exit status; by default it reflects only the last command's exit status. - Forgetting that each side of a pipe runs in its own subshell, so variables set inside a piped command do not persist afterward.
|connects one command's stdout directly to the next command's stdin.- By default,
$?after a pipeline reflects only the last command's exit status. set -o pipefailmakes the pipeline's exit status the first non-zero status among all commands.- Commands can be chained with
&&(run next only on success) and||(run next only on failure).
Chapter Quiz — Complete all 13 topics to unlock
0/13 topics done
Complete these topics first:
- Function Basics
- The read Command and Here-Strings
- Function Arguments
- stdin, stdout, stderr and File Descriptors
- Return Values
- Redirection Operators
- Local Variables
- Pipes and Chaining Commands
- Recursive Functions
- Here-Documents (<<EOF)
- Function Libraries
- The tee Command
- Discarding Output with /dev/null