File Descriptors - Intermediate

Combining and Duplicating Streams

The & Notation

The & in redirections means “file descriptor”:

# Redirect stderr to wherever stdout is going
command 2>&1
 
# Shorthand: redirect both stdout and stderr to file
command &> output.txt    # Same as: command > output.txt 2>&1
command &>> output.txt   # Append version

Order Matters!

# WRONG: stderr still goes to terminal
command > file.txt 2>&1  # Correct order
 
command 2>&1 > file.txt  # WRONG: stderr goes to original stdout

Common Patterns

Silencing Output

# Discard all output
command > /dev/null 2>&1
 
# Discard only errors
command 2> /dev/null
 
# Discard output but keep errors
command > /dev/null

Logging Patterns

#!/bin/bash
# log-wrapper.sh - Log all output while still displaying it
 
# Log both stdout and stderr to file while showing on screen
./mycommand 2>&1 | tee output.log
 
# Separate error logging
./mycommand 2> >(tee -a error.log >&2) | tee -a output.log

Conditional Output

# verbose.sh - Control output verbosity
VERBOSE=${VERBOSE:-0}
 
debug() {
    [ "$VERBOSE" -eq 1 ] && echo "[DEBUG] $*" >&2
}
 
info() {
    echo "[INFO] $*"
}
 
error() {
    echo "[ERROR] $*" >&2
}
 
# Usage
debug "This only shows if VERBOSE=1"
info "This always shows"
error "This goes to stderr"

Reading and Writing Simultaneously

# Process a file in-place (careful!)
while IFS= read -r line; do
    echo "PROCESSED: $line"
done < input.txt > temp.txt && mv temp.txt input.txt