wiki:shell-io
Table of Contents
Shell I/O and Redirection
Redirection
Redirect standard input, output, and error between files and file descriptors. File descriptor 1 is stdout, 2 is stderr, 0 is stdin.
>— Write stdout to file (truncates if exists)>>— Append stdout to file<— Read stdin from file2>— Redirect stderr to file&>— Redirect both stdout and stderr
# Redirect output to file ls > files.txt # Append to file echo "more content" >> files.txt # Redirect both stdout and stderr command > output.txt 2>&1 # Redirect stderr only command 2> errors.log # Discard output command > /dev/null 2>&1 # Read input from file sort < unsorted.txt
Combine redirections to separate stdout and stderr streams:
# Stdout goes to output.txt, stderr to error.txt script.sh > output.txt 2> error.txt # Send stderr to stdout script.sh 2>&1 # Send stderr to stdout, then pipe to grep script.sh 2>&1 | grep "error"
Pipelines and tee
Pipe the stdout of one command into the stdin of another with |. Chain multiple commands to transform data.
# Count lines in a file cat myfile.txt | wc -l # Chain commands: list, sort, count unique ls | sort | uniq | wc -l # Find large files and sort by size find . -type f -exec ls -lh {} \; | sort -k5 -h
Use tee to write to a file and stdout simultaneously. Useful for logging intermediate pipeline output.
# Capture output to file while still printing it cat data.txt | tee backup.txt | grep "important" # Append mode with tee command | tee -a logfile.txt # Tee in a pipeline with multiple commands generate_report | tee report.txt | mail -s "Report" admin@example.com
Command Substitution
Run a command and substitute its output in-place with $(command) or `command` . The $() syntax is preferred (nestable, more readable).
# Assign command output to variable files=$(ls *.txt) count=$(wc -l < data.txt) # Use in string echo "Found $(ls -1 | wc -l) files" # Nested command substitution (only works with $(), not backticks) total=$(( $(wc -l < file1.txt) + $(wc -l < file2.txt) ))
Be careful with whitespace: command substitution removes trailing newlines but preserves embedded whitespace. Quote variables to preserve spaces and newlines.
# Without quotes: loses structure for file in $(ls) # Splits on whitespace, breaks with spaces in names echo $file done # With quotes: preserves structure for file in $(ls) do echo "$file" # Correctly handles spaces and newlines done # Alternative: use -print0 with while read ls -print0 | while IFS= read -rd '' file; do echo "$file" done
wiki/shell-io.md · Last modified: by 127.0.0.1
