Pipes & Redirection
Pipes chain commands together so one program's output becomes the next program's input — the idea that makes small, single-purpose Unix tools genuinely powerful when combined.
The pipe operator
| sends one command's standard output directly into the next command's standard input:
cat access.log | grep "ERROR" | wc -l
7
This chain reads access.log, keeps only lines containing "ERROR", and counts how many lines are left — three small tools combining to answer "how many error lines are there?" without any of them needing to know about the others.
Redirecting stderr separately
Bash keeps standard output (1) and standard error (2) as separate streams, and you can redirect each independently:
./backup.sh > success.log 2> errors.log
Normal output goes to success.log; anything the script writes to stderr (typically error messages) goes to errors.log instead — keeping the two from getting mixed together in one file. &> both.log sends both streams to the same file if you want them combined.
Chaining with && and ||
&& runs the next command only if the previous one succeeded; || runs the next command only if the previous one failed:
mkdir backups && echo "Folder created" cp missing.txt backups/ || echo "Copy failed, file not found"
Folder created Copy failed, file not found
cat file | while read line; do count=$((count+1)); done — disappears once the pipeline finishes; the count outside the pipe never sees the updates. If you need the result outside the pipe, avoid piping into the loop (redirect from the file with < instead, as in the previous lesson) or capture the final value some other way.