Shell Pipes Explained: How `|` Works in the Command Line
A practical guide to the pipe operator `|`: how it connects commands, common patterns, and useful examples.
Shell Pipes Explained: How | Works in the Command Line
The pipe operator (|) is one of the most powerful ideas in the Unix shell. It connects the output of one command directly into the input of the next command, enabling quick, composable workflows.
What a Pipe Does
In plain terms:
commandA | commandB
means:
commandAwrites to stdout (standard output)commandBreads from stdin (standard input)- the pipe connects them
This lets you chain small tools together without temporary files.
Simple Examples
List files and filter by keyword:
ls -la | grep "log"
Count how many matches you have:
rg "error" app.log | wc -l
Sort processes by memory usage:
ps aux | sort -k 4 -r | head -n 5
Why Pipes Are Powerful
- Composability: build complex workflows from small tools
- Speed: no intermediate files
- Clarity: each command does one thing well
Unix tools are designed to work like LEGO: the pipe is the connector.
Common Patterns
Search → Filter → Act
rg "TODO" -n | fzf | awk -F: '{print $1\":\"$2}' | xargs -I{} ${EDITOR:-vim} {}
Produce → Reduce
du -sh * | sort -h | tail -n 5
Generate → Transform
printf "%s\n" one two three | tr 'a-z' 'A-Z'
Pipes vs Redirects
Pipes are not the same as redirects:
>writes output to a file:ls > files.txt|sends output to another command:ls | grep "src"
You can combine them:
rg "error" app.log | tee errors.txt | wc -l
Here tee writes to a file and passes the stream along.
Exit Codes and Failures
By default, only the last command's exit status is returned. In Bash, you can inspect all statuses with:
echo ${PIPESTATUS[@]}
In Zsh:
echo $pipestatus
This matters when you need to know if an earlier command failed.
Practical Recipes
-
Find and open a file:
rg --files | fzf | xargs -I{} ${EDITOR:-vim} {} -
Kill a selected process:
ps aux | fzf -m | awk '{print $2}' | xargs kill -
Extract columns from CSV:
cat data.csv | cut -d, -f1,3 | column -t -s,
Takeaway
The pipe is the glue of the Unix philosophy: small tools connected into powerful pipelines. Once you get comfortable with |, your command line becomes a programmable toolkit rather than a list of isolated commands.