Bash Script to Rotate Log Files Automatically
mv logfile.log logfile.log.1; rm -f logfile.log.5 to rotate logs up to 5 versions.Examples
How to Think About It
Algorithm
Code
#!/bin/bash LOGFILE="logfile.log" MAX=5 if [ ! -f "$LOGFILE" ]; then echo "No log file to rotate." exit 0 fi # Remove oldest log if [ -f "$LOGFILE.$MAX" ]; then rm -f "$LOGFILE.$MAX" fi # Shift logs for ((i=MAX-1; i>=1; i--)); do if [ -f "$LOGFILE.$i" ]; then mv "$LOGFILE.$i" "$LOGFILE.$((i+1))" fi done # Rotate current log mv "$LOGFILE" "$LOGFILE.1" # Create new empty log > "$LOGFILE" echo "Log rotation complete."
Dry Run
Let's trace rotating logfile.log when logfile.log.1 to logfile.log.4 exist and logfile.log has new data.
Check if logfile.log exists
logfile.log exists, continue
Delete oldest log if exists
logfile.log.5 does not exist, no deletion
Shift logs up by one
logfile.log.4 -> logfile.log.5 logfile.log.3 -> logfile.log.4 logfile.log.2 -> logfile.log.3 logfile.log.1 -> logfile.log.2
Rename current log
logfile.log -> logfile.log.1
Create new empty logfile.log
logfile.log is now empty
| Operation |
|---|
| Check logfile.log exists |
| Remove logfile.log.5 if exists |
| Move logfile.log.4 to logfile.log.5 |
| Move logfile.log.3 to logfile.log.4 |
| Move logfile.log.2 to logfile.log.3 |
| Move logfile.log.1 to logfile.log.2 |
| Rename logfile.log to logfile.log.1 |
| Create empty logfile.log |
Why This Works
Step 1: Check for log file
The script first checks if logfile.log exists to avoid errors when rotating.
Step 2: Delete oldest log
It removes the oldest rotated log (e.g., logfile.log.5) to keep only a fixed number of backups.
Step 3: Shift logs
Older logs are renamed to the next number to make room for the new rotated log.
Step 4: Rotate current log
The current log is renamed to logfile.log.1, archiving it.
Step 5: Create new log
A new empty logfile.log is created so logging can continue fresh.
Alternative Approaches
sudo apt-get install logrotate # Create /etc/logrotate.d/mylog with config: # /path/to/logfile.log { # rotate 5 # daily # missingok # notifempty # copytruncate # } # Then run: logrotate /etc/logrotate.d/mylog
#!/bin/bash LOGFILE="logfile.log" MAX=5 if [ ! -f "$LOGFILE" ]; then exit 0; fi if [ -f "$LOGFILE.$MAX.gz" ]; then rm -f "$LOGFILE.$MAX.gz"; fi for ((i=MAX-1; i>=1; i--)); do if [ -f "$LOGFILE.$i.gz" ]; then mv "$LOGFILE.$i.gz" "$LOGFILE.$((i+1)).gz"; fi if [ -f "$LOGFILE.$i" ]; then gzip "$LOGFILE.$i"; fi done mv "$LOGFILE" "$LOGFILE.1" gzip "$LOGFILE.1" > "$LOGFILE" echo "Compressed log rotation complete."
Complexity: O(n) time, O(1) space
Time Complexity
The script loops through existing rotated logs once, so time grows linearly with the number of rotations.
Space Complexity
No extra memory is used beyond renaming files; operations are in-place on disk.
Which Approach is Fastest?
The simple Bash script is fast for small numbers of rotations; using logrotate adds overhead but offers more features.
| Approach | Time | Space | Best For |
|---|---|---|---|
| Bash script rotation | O(n) | O(1) | Simple setups with few logs |
| logrotate tool | O(n) | O(1) | Complex rotation policies and automation |
| Compression during rotation | O(n) | O(1) | Saving disk space with CPU cost |