Module 3 · Text, redirection and pipes
Pipes: connecting commands with |
Feed one command's output straight into another and start building the small chains that make Unix productive.
What you will learn
- Explain what a pipe does with stdout and stdin.
- Chain two or more commands and read a pipeline left to right.
- Tell the difference between a pipe and a redirection and combine both.
A redirection connects a command to a file. A pipe connects a command to another command: a | b runs both at once, with everything a writes to its stdout arriving at b's stdin. No temporary file, no waiting for a to finish first. The vertical bar is the single most important character in the Unix toolbox, because it lets small programs that each do one thing be combined into something none of them does alone.
Reading a pipeline
Read left to right and ask at each bar "what text is flowing through here?". In ls /bin | head -5, a list of names flows out of ls and head keeps the first five. In cat words.txt | sort | uniq -c | sort -rn, the lines of the file are sorted, collapsed into counted groups, then sorted again by that count, biggest first. Each stage is a plain command you could run alone; the pipeline is just the glue.
Commands that read stdin when given no file name are called filters: sort, uniq, wc, head, tail, grep, tr, cut, sed, awk and many more. Commands that produce lists, like ls, ps, find or cat, usually sit at the left end. Only stdout travels through a pipe; stderr still goes to the terminal, unless you add 2>&1 before the bar.
~% ls /bin | wc -l
73
~% ls /bin | head -3
arch
ash
busybox
~% cat /etc/passwd | cut -d: -f1 | sort | head -4
bin
daemon
mail
nobody
~% ls /root /nope 2>&1 | wc -l
2
~% ls /bin | grep grep
egrep
fgrep
grep
Pipe or redirection?
| You want to | Use | Example |
|---|---|---|
| keep output in a file | > or >> | ls > list.txt |
| process output with another command | \| | ls \| wc -l |
| process it and keep the result | both | ls \| sort > list.txt |
| feed a file into a filter | < or an argument | sort < f / sort f |
Pipelines and exit status
A pipeline's exit status is that of its last command. grep nothing file | wc -l succeeds even when grep found nothing, because wc ran fine and printed 0. Keep that in mind later when you use && or if around pipelines: test the stage that matters, or restructure so it comes last.
Long pipelines can be split across lines: a line that ends in | continues on the next one, which is how you will see them written in scripts. Build them incrementally: run the first command, check the output looks right, add a stage, check again.
Commands in this lesson
| Command | What it does |
|---|---|
cmd1 | cmd2 | Connect cmd1's stdout to cmd2's stdin. |
ls /bin | wc -l | Count the entries in /bin. |
cmd | head -5 | Keep only the first five lines of cmd's output. |
cmd 2>&1 | less | Page through output and errors together. |
cmd1 | cmd2 > file | Process, then save the final result. |
Quiz
What does `a | b` connect?
- a's stdout to b's stdin
- a's stdin to b's stdout
- a's stderr to b's stdin
What does `ls /etc | wc -l` print?
- The number of entries in /etc
- The size of /etc in bytes
- The listing of /etc followed by a count
Do error messages from the first command travel through a pipe?
- Yes, always
- No; only stdout does, unless you add 2>&1 before the bar
- Only if the second command is grep
Whose exit status does a pipeline report?
- The first command's
- The last command's
- The highest of all of them
Practice
/root/lab/l24/words.txt has twelve words, one per line. Take its first three lines with head, sort them through a pipe, and save the result in /root/lab/l24/top3.txt.
Using a pipe into `wc -l`, store the number of lines of /root/lab/l24/words.txt in /root/lab/l24/count.txt. The file must contain just the number.
Write a pipeline that prints how many entries the directory /bin contains.
Open this lesson in the app to do the tasks in a real Linux machine and have them checked.