Writing Files
Learn to write data to files using redirection, appending, and here documents. Master safe file writing practices.
Basic Output Redirection
#!/bin/bash
# Overwrite file (creates if doesn't exist)
echo "Hello, World!" > output.txt
# Append to file
echo "Another line" >> output.txt
# Multiple lines
echo "Line 1" > file.txt
echo "Line 2" >> file.txt
echo "Line 3" >> file.txt
Command Output to File
#!/bin/bash
# Save command output
ls -la > listing.txt
date > timestamp.txt
# Save with append
ps aux >> processes.log
# Discard output
command > /dev/null
# Discard errors too
command > /dev/null 2>&1
Exercise: Write to File
Create and append to a file:
Here Documents
Write multi-line content:
#!/bin/bash
# Basic here document
cat << EOF > config.txt
host=localhost
port=8080
debug=true
EOF
# With variable expansion
NAME="production"
cat << EOF > settings.txt
Environment: $NAME
Created: $(date)
EOF
# Literal (no expansion) - quote EOF
cat << 'EOF' > script.sh
#!/bin/bash
echo "Hello, $USER"
EOF
Here Strings
For single-line input:
#!/bin/bash
# Here string
cat <<< "This is a here string" > file.txt
# Useful with commands expecting stdin
grep "pattern" <<< "$VARIABLE"
Printf for Formatted Output
#!/bin/bash
# Formatted output to file
printf "Name: %s\nAge: %d\n" "Alice" 30 > person.txt
# With field widths
printf "%-10s %5d\n" "Alice" 95 > scores.txt
printf "%-10s %5d\n" "Bob" 87 >> scores.txt
# Hex, octal, etc.
printf "Decimal: %d, Hex: %x, Octal: %o\n" 255 255 255 > numbers.txt
Exercise: Here Document
Use here document for multi-line:
Writing from Loops
#!/bin/bash
# Redirect entire loop output
for i in {1..5}; do
echo "Line $i"
done > output.txt
# Append from loop
for file in *.txt; do
echo "$file: $(wc -l < "$file") lines"
done >> report.txt
# Build content in variable
CONTENT=""
for i in 1 2 3; do
CONTENT+="Item $i\n"
done
echo -e "$CONTENT" > items.txt
Atomic File Writing
Write safely to avoid corruption:
#!/bin/bash
# Write to temp file, then move
TMPFILE=$(mktemp)
echo "New content" > "$TMPFILE"
mv "$TMPFILE" final.txt
# Or with trap for cleanup
TMPFILE=$(mktemp)
trap 'rm -f "$TMPFILE"' EXIT
cat << EOF > "$TMPFILE"
Configuration data
That could be complex
EOF
# Only move if successful
mv "$TMPFILE" config.txt
trap - EXIT # Clear trap
Tee: Write and Display
Write to file while also showing output:
#!/bin/bash
# Write to file AND stdout
echo "Hello" | tee output.txt
# Append mode
echo "More text" | tee -a output.txt
# Write to multiple files
echo "Shared" | tee file1.txt file2.txt file3.txt
# Capture command output while viewing
ls -la | tee listing.txt
File Descriptors
Advanced file control:
#!/bin/bash
# Open file for writing (fd 3)
exec 3> output.txt
echo "Line 1" >&3
echo "Line 2" >&3
echo "Line 3" >&3
# Close file descriptor
exec 3>&-
# Append mode
exec 4>> append.txt
echo "Appended" >&4
exec 4>&-
Error Handling
Handle write failures:
#!/bin/bash
OUTPUT_FILE="/path/to/output.txt"
# Check directory exists
PARENT_DIR=$(dirname "$OUTPUT_FILE")
if [[ ! -d "$PARENT_DIR" ]]; then
mkdir -p "$PARENT_DIR" || {
echo "Failed to create directory" >&2
exit 1
}
fi
# Check file is writable (if exists)
if [[ -e "$OUTPUT_FILE" && ! -w "$OUTPUT_FILE" ]]; then
echo "File not writable: $OUTPUT_FILE" >&2
exit 1
fi
# Write with error check
if ! echo "Content" > "$OUTPUT_FILE"; then
echo "Failed to write file" >&2
exit 1
fi
echo "Successfully wrote to $OUTPUT_FILE"
Key Takeaways
>overwrites,>>appends- Here documents (
<< EOF) write multiple lines - Use
printffor formatted output - Quote
'EOF'to prevent variable expansion - Use temp file + mv for atomic writes
teewrites to file and stdout- Always check write success in critical scripts
- Use file descriptors for advanced control

