Bash Pipes and Redirection
Pipes and redirection are among the most powerful features in Bash. They connect commands together and control where data flows — from one command to another, or between commands and files. Mastering these concepts allows writing compact and efficient one-liners.
Standard Streams
Every command in Linux uses three data channels called standard streams.
┌──────────────────────────────────────────────────────┐ │ │ │ stdin (Standard Input) → File descriptor: 0 │ │ Where a command reads input from │ │ Default: keyboard │ │ │ │ stdout (Standard Output) → File descriptor: 1 │ │ Where a command writes normal output │ │ Default: terminal screen │ │ │ │ stderr (Standard Error) → File descriptor: 2 │ │ Where error messages appear │ │ Default: terminal screen │ │ │ └──────────────────────────────────────────────────────┘
Output Redirection
Redirect stdout to a File
ls -l > filelist.txt
This saves the output of ls -l into filelist.txt. The screen shows nothing — the output went to the file.
Append stdout to a File
echo "New entry" >> filelist.txt
Redirect stderr to a File
ls /nonexistent_dir 2> error.log
Redirect Both stdout and stderr to One File
command > output.txt 2>&1
Or in a shorter modern form:
command &> output.txt
Redirection Summary Table
| Syntax | Meaning |
|---|---|
cmd > file | Redirect stdout to file (overwrite) |
cmd >> file | Redirect stdout to file (append) |
cmd 2> file | Redirect stderr to file |
cmd 2>> file | Append stderr to file |
cmd &> file | Redirect both stdout and stderr to file |
cmd < file | Use file as stdin (input) |
cmd 2>/dev/null | Discard error messages (send to /dev/null) |
Input Redirection
#!/bin/bash while read line do echo "Line: $line" done < names.txt
Pipes – Connecting Commands
A pipe | takes the output of one command and feeds it directly as the input of another command. No temporary file is needed.
┌────────────┐ ┌────────────┐ ┌────────────┐ │ Command 1 │─────►│ Command 2 │─────►│ Command 3 │ │ produces │ pipe │ processes │ pipe │ displays │ │ output │ | │ it │ | │ result │ └────────────┘ └────────────┘ └────────────┘
Example – Count Files in a Directory
ls | wc -l
The output of ls (list of files) goes into wc -l (count lines). The result is the total number of files.
Example – Find and Count Errors in a Log
cat server.log | grep "ERROR" | wc -l
Example – View Long Output Page by Page
ls -la | less
Example – Sort and Remove Duplicates
cat names.txt | sort | uniq
Useful Commands Commonly Used with Pipes
| Command | Purpose |
|---|---|
grep | Filter lines matching a pattern |
sort | Sort lines alphabetically or numerically |
uniq | Remove duplicate consecutive lines |
wc | Count lines, words, or characters |
cut | Extract specific columns or characters |
awk | Process and format columns of text |
sed | Search and replace text in a stream |
head | Show the first N lines |
tail | Show the last N lines |
tr | Translate or delete characters |
Here Document (heredoc)
A heredoc sends a block of multi-line text as input to a command. Use <<LABEL to start and the same label on its own line to end.
#!/bin/bash cat <<MESSAGE Welcome to eStudy247. This is a multi-line message. Bash makes it easy. MESSAGE
Output:
Welcome to eStudy247. This is a multi-line message. Bash makes it easy.
Here String
A here string passes a single string as stdin to a command using <<<.
#!/bin/bash word="hello" tr 'a-z' 'A-Z' <<< "$word"
Output:
HELLO
tee Command – Output to Screen AND a File
The tee command writes output to both the terminal and a file at the same time.
ls -l | tee filelist.txt
Output appears on screen and also saves to filelist.txt.
Practical Example – System Report Generator
#!/bin/bash
reportfile="system_report.txt"
{
echo "=== System Report ==="
echo "Date: $(date)"
echo ""
echo "--- Disk Usage ---"
df -h
echo ""
echo "--- Memory Usage ---"
free -h
echo ""
echo "--- Running Processes ---"
ps aux | head -10
} > $reportfile
echo "Report saved to $reportfile"
Key Takeaways
- Use
>to redirect output to a file and>>to append. - Use
2>to redirect error messages to a file. - Use
2>/dev/nullto silently discard error messages. - Use
|(pipe) to connect commands and pass data between them. - Use
teeto write output to both screen and file simultaneously. - Heredoc (
<<) passes multi-line text as input to a command.
