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

SyntaxMeaning
cmd > fileRedirect stdout to file (overwrite)
cmd >> fileRedirect stdout to file (append)
cmd 2> fileRedirect stderr to file
cmd 2>> fileAppend stderr to file
cmd &> fileRedirect both stdout and stderr to file
cmd < fileUse file as stdin (input)
cmd 2>/dev/nullDiscard 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

CommandPurpose
grepFilter lines matching a pattern
sortSort lines alphabetically or numerically
uniqRemove duplicate consecutive lines
wcCount lines, words, or characters
cutExtract specific columns or characters
awkProcess and format columns of text
sedSearch and replace text in a stream
headShow the first N lines
tailShow the last N lines
trTranslate 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/null to silently discard error messages.
  • Use | (pipe) to connect commands and pass data between them.
  • Use tee to write output to both screen and file simultaneously.
  • Heredoc (<<) passes multi-line text as input to a command.

Leave a Comment