Created
January 26, 2022 15:40
-
-
Save mzpqnxow/88761eaaecc393ea3e75ab8040465eca to your computer and use it in GitHub Desktop.
Bash function to roll log files (or any other file) with a maximum keep
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# | |
# Function to roll files in the way that logrotate rolls log files | |
# Keeps up to the specified amount of files | |
# | |
# | |
# (C) 2022, AG | |
# | |
set -eu | |
# Globals, optional | |
declare -r SAVE_COUNT=10 | |
declare COMPRESS=xz | |
declare EXT=".xz" | |
# | |
# roll_file() | |
# Description | |
# ----------- | |
# Roll a file up to a maximum keep count in the way that logrotate | |
# rolls and keeps log file | |
# | |
# Arguments | |
# --------- | |
# basefile: The filename that should be rolled | |
# compressor: Optional; The name of the compression program (e.g. xz) | |
# ext: Optional; The extension added by the compression program, including the dot (e.g. .xz) | |
# maxkeep: Optional; The total number of rolled files to keep | |
# | |
# Caveats | |
# ------- | |
# This will not clean up files that are above the keep count. For example, if | |
# your keep count is 5 and you basefile.8 exists, it will not be cleaned up. It | |
# will properly clean up basefile.5. If you're consistent in how you use this it | |
# should not be an issue | |
# | |
# Notes | |
# ----- | |
# There must be a simpler and more elegant way to do this, but this works | |
# reliably so it's good enough :> | |
# | |
roll_file() { | |
local ext="${EXT:-}" | |
local -r basefile="$1" | |
local -r compressor="${2:-${COMPRESS:-}}" | |
local -r ext="${3:-${EXT:-}}" | |
local -r maxkeep="${4:-$SAVE_COUNT}" | |
if [ -e "$basefile" ]; then | |
for i in $(seq $maxkeep -1 1); do | |
nextfile="$basefile.$i$ext" | |
next_keep_file="$basefile.$((i + 1))$ext" | |
[[ ! -e "$nextfile" ]] && continue | |
if [ $i -eq $maxkeep ]; then | |
# Reached maximum keep count, remove it; it will be replaced | |
rm -f "$nextfile" | |
continue | |
fi | |
mv "$nextfile" "$next_keep_file" | |
done | |
# Finally, roll the base file and compress it if necessary | |
local -r roll_to="$basefile.1" | |
mv "$basefile" "$roll_to" | |
if [ "$compressor" != "" ]; then | |
# compress the rolled file if compressor is set and it exists | |
if [ ! $(command -v "$compressor") ]; then | |
echo "$compressor does not exist; file $basefile was rolled to file $roll_to but *not* compressed!" | |
echo "Exiting ..." | |
exit | |
fi | |
# Remove if it already exists | |
rm -f "$roll_to$ext" | |
# Compress it | |
"$compressor" "$roll_to" | |
fi | |
fi | |
} | |
# Roll the file "somefile", using the global defaults | |
roll_file somefile | |
# Roll the file "somefile" using bzip2 to compress | |
roll_file somefile bzip2 .bz2 | |
# Roll the file "somefile" using bzip2 to compress; keep only the latest 5 copies | |
roll_file somefile bzip2 .bz2 5 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment