File Writing
Writing files is essential for creating logs, configuration files, reports, and data exports. Bash provides multiple methods for file writing, from simple echo to formatted printf output. You'll also learn safe writing techniques to prevent data loss!
Basic File Writing Methods
The most common ways to write files are using echo, printf, and here documents with output redirection.
Click Run to execute your code
| Method | Description | Example |
|---|---|---|
> |
Overwrite file (create if not exists) | echo "text" > file.txt |
>> |
Append to file | echo "text" >> file.txt |
cat > file << EOF |
Here document (multi-line) | cat > config.txt << EOF ... EOF |
printf |
Formatted output | printf "%s: %d\n" "Count" 5 > file |
tee |
Write to file AND stdout | echo "text" | tee file.txt |
>- Creates new file or overwrites existing content (destructive!)>>- Creates new file or appends to existing content (safe for logs)
Printf for Formatted Output
The printf command offers precise control over output formatting, making it perfect for tables, reports, and structured data.
Click Run to execute your code
| Format | Description | Example |
|---|---|---|
%s |
String | printf "%s" "hello" |
%d |
Integer | printf "%d" 42 |
%f / %.2f |
Float / with precision | printf "%.2f" 3.14159 |
%10s |
Right-padded (10 chars) | printf "%10s" "hi" |
%-10s |
Left-padded (10 chars) | printf "%-10s" "hi" |
%05d |
Zero-padded integer | printf "%05d" 42 โ 00042 |
printf instead of echo when you need consistent behavior across systems. echo behaves differently on various platforms, while printf is standardized.
Safe File Writing Techniques
Production scripts need robust file writing that handles errors and prevents data loss. Learn professional patterns for safe file operations.
Click Run to execute your code
Safe Writing Patterns
# 1. Atomic write with temp file
temp=$(mktemp)
echo "content" > "$temp" && mv "$temp" "target.txt"
# 2. Write with backup
cp "file.txt" "file.txt.bak"
echo "new content" > "file.txt"
# 3. Check write success
if echo "data" > "file.txt"; then
echo "Write succeeded"
else
echo "Write failed!" >&2
exit 1
fi
# 4. noclobber - prevent accidental overwrite
set -o noclobber
echo "test" > existing.txt # Fails if exists
echo "test" >| existing.txt # Force overwrite
# 5. Write to stderr for errors
echo "Error: Something wrong" >&2
> redirection - it destroys existing file content immediately! Consider using set -o noclobber in interactive shells, or always create backups before overwriting important files.
Multi-line Writing with Here Documents
Here documents are perfect for writing multi-line content like configuration files, scripts, or templates.
# Basic here document
cat > config.txt << 'EOF'
[settings]
debug = true
port = 8080
host = localhost
EOF
# With variable expansion (unquoted EOF)
name="MyApp"
version="1.0"
cat > config.txt << EOF
app_name=$name
app_version=$version
generated=$(date)
EOF
# Append with here document
cat >> log.txt << EOF
[$(date)] New entry added
EOF
# Here string (single line)
cat <<< "Single line content" > file.txt
<< 'EOF'- No variable expansion (literal text)<< EOF- Variables and commands are expanded
Common Mistakes
1. Accidentally overwriting important files
# Dangerous - overwrites without warning
echo "test" > /etc/important.conf
# Safer - check first
if [[ -f "important.conf" ]]; then
cp "important.conf" "important.conf.bak"
fi
echo "test" > "important.conf"
2. Forgetting quotes in filenames
# Wrong - fails with spaces in filename
echo "data" > $filename
# Correct - always quote
echo "data" > "$filename"
3. Not checking write permissions
# Wrong - might fail silently
echo "log entry" >> /var/log/app.log
# Correct - check first
if [[ -w "/var/log/app.log" ]]; then
echo "log entry" >> "/var/log/app.log"
else
echo "Cannot write to log file" >&2
fi
4. Using echo -e inconsistently
# Inconsistent - echo -e behavior varies by system
echo -e "line1\nline2"
# Consistent - use printf
printf "line1\nline2\n"
# Or use $'...' syntax
echo $'line1\nline2'
Exercise: Log File Generator
Task: Create a script that generates a formatted log file!
Requirements:
- Create a log file with a header (app name, generated date)
- Add several timestamped log entries
- Create a summary section with line count
- Use printf for aligned columns
Show Solution
#!/bin/bash
# Log File Generator
log_file="/tmp/app.log"
# Write header
cat > "$log_file" << EOF
========================================
Application Log
Generated: $(date '+%Y-%m-%d %H:%M:%S')
========================================
EOF
# Add timestamped entries using printf
{
printf "%-20s %-8s %s\n" "TIMESTAMP" "LEVEL" "MESSAGE"
printf "%-20s %-8s %s\n" "--------------------" "--------" "------------------------"
printf "%-20s %-8s %s\n" "$(date '+%H:%M:%S.%3N')" "INFO" "Application started"
printf "%-20s %-8s %s\n" "$(date '+%H:%M:%S.%3N')" "DEBUG" "Loading configuration"
printf "%-20s %-8s %s\n" "$(date '+%H:%M:%S.%3N')" "INFO" "Connected to database"
printf "%-20s %-8s %s\n" "$(date '+%H:%M:%S.%3N')" "WARN" "Cache miss detected"
printf "%-20s %-8s %s\n" "$(date '+%H:%M:%S.%3N')" "INFO" "Request processed"
} >> "$log_file"
# Add summary
{
echo ""
echo "========================================"
echo "Summary"
echo "Total entries: $(grep -c "^[0-9]" "$log_file")"
echo "========================================"
} >> "$log_file"
echo "Log file created:"
cat "$log_file"
rm -f "$log_file"
Summary
- Overwrite:
>creates or overwrites file - Append:
>>adds to existing file - printf: Formatted output with precise control (
%s,%d,%.2f) - Here Document: Multi-line content with
<< EOF ... EOF - tee: Write to file AND display (
echo | tee file) - Atomic Write: Use temp file then
mvfor safety - noclobber:
set -o noclobberprevents accidental overwrites
What's Next?
Now that you can read and write files, let's learn about File Manipulation. You'll master copying, moving, deleting files, and working with file permissions using cp, mv, rm, chmod, and more!
Enjoying these tutorials?