SyntaxStudy
Sign Up
Linux / Bash Beginner 1 min read

Advanced Redirection and tee

The `tee` command reads from stdin and writes to both stdout and one or more files simultaneously. This is invaluable when you want to see the output of a pipeline in the terminal while also saving it to a file. The `-a` flag appends to the file rather than overwriting it. `tee` can also broadcast to multiple files at once. Process substitution, available in Bash and Zsh, treats the output of a command as a file using the syntax `<(command)`. This allows you to pass the output of a command where a filename argument is expected. For example, `diff <(ls dir1) <(ls dir2)` compares the file listings of two directories without creating temporary files. Named pipes (FIFOs) created with `mkfifo` provide a file-based inter-process communication mechanism. Data written to the FIFO blocks until another process reads it, enabling coordinated communication between otherwise unrelated processes. While less common in everyday use, they appear in deployment pipelines and logging architectures where processes need to hand off data.
Example
# tee: display output AND save to file
ls -la | tee filelist.txt

# tee: append to file instead of overwrite
command_output | tee -a /var/log/deploy.log

# tee: write to multiple files
echo "Status: OK" | tee status.txt backup_status.txt

# tee in the middle of a pipeline
cat /var/log/syslog | grep "error" | tee errors_raw.txt | wc -l

# Capture output with sudo (tee workaround)
echo "new_config=value" | sudo tee /etc/app/config.conf > /dev/null

# ---- Process substitution ----

# Compare directory listings without temp files
diff <(ls /etc/nginx/) <(ls /etc/apache2/)

# Compare sorted versions of two files
diff <(sort file1.txt) <(sort file2.txt)

# Use command output as a file argument
wc -l <(find / -name "*.log" 2>/dev/null)

# Feed command output into a while loop (avoids subshell)
while IFS= read -r line; do
    echo "Processing: $line"
done < <(find /var/log -name "*.log" -mtime -1)

# ---- Named pipes (FIFOs) ----

# Create a named pipe
mkfifo /tmp/mypipe

# Writer process (runs in background)
ls -la > /tmp/mypipe &

# Reader process (consumes from pipe)
cat /tmp/mypipe

# Clean up
rm /tmp/mypipe