File Operations in Shell Scripts
Working with files is a fundamental part of shell scripting. You frequently need to read configuration files, write logs, or process data.
Redirection
Output redirection allows you to write command output to a file instead of the terminal.
>: Overwrites the file with new content.>>: Appends content to the end of the file.
# Overwrite
echo "Starting log..." > app.log
# Append
echo "User logged in at $(date)" >> app.log
Reading Files Line by Line
The most robust way to read a file line by line in bash is using a while loop combined with the read command.
FILE="servers.txt"
# Ensure the file exists before reading
if [ -f "$FILE" ]; then
while IFS= read -r LINE; do
echo "Server: $LINE"
done < "$FILE"
else
echo "File not found: $FILE"
fi
(The IFS= prevents trimming leading/trailing whitespace, and -r prevents backslashes from acting as escape characters).
File Descriptors and Redirection
Every process has three default file descriptors:
0: Standard Input (stdin)1: Standard Output (stdout)2: Standard Error (stderr)
You can redirect errors to a separate file or discard them.
# Redirect errors to error.log
ls /nonexistent_directory 2> error.log
# Redirect both stdout and stderr to the same file
ls / 2>&1 > output.log
# Or the modern shortcut:
ls / &> output.log
Finding and Processing Files
You can combine find with loops to process multiple files matching a pattern.
# Find all .log files and compress them
find /var/log -type f -name "*.log" | while read -r LOG_FILE; do
echo "Compressing $LOG_FILE"
gzip "$LOG_FILE"
done
Best Practices
- Always check if a file exists and is readable/writable before attempting operations on it.
- Use
>>carefully so you don't accidentally bloat log files indefinitely. - Use
IFS= read -rfor safely reading line by line without corrupting data.