Skip to content

Instantly share code, notes, and snippets.

@DataWraith
Created May 7, 2010 19:11
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DataWraith/393883 to your computer and use it in GitHub Desktop.
Save DataWraith/393883 to your computer and use it in GitHub Desktop.
Script to clean Polipo's cache once free space runs low
#!/bin/zsh
# This script deletes the least-recently used (LRU) files from Polipo's cache
# once the partition it is on has less than $min_disk_free Bytes of free space
# left.
#
# It's meant to be used as a cron job, and it's a little more complicated than
# it needs to be, because I wrote it mostly to learn zsh.
local cache_dir="/var/cache/polipo/"
local logfile="/var/log/polipo_cache_clean.log"
local min_disk_free=$((1024*1024*1024/3))
local cur_disk_free=$(df -B1 $cache_dir | tail -1 | awk '{print $4}')
# Let's first see if we can make Pacman reclaim space
if [ $cur_disk_free -lt $min_disk_free ]
then
pacman -qSc --noconfirm
cur_disk_free=$(df -B1 $cache_dir | tail -1 | awk '{print $4}')
fi
if [ $cur_disk_free -lt $min_disk_free ]
then
local to_free=$(($min_disk_free - $cur_disk_free))
typeset -A deleted_bytes
typeset -A deleted_files
printf "[%s] Cleaning cache, %s Bytes to free. \n" "$(date +"%F %T")" "$(/usr/bin/printf "%'u" "$to_free")" >> $logfile
# Tell polipo we're messing with the cache
killall -s SIGUSR1 polipo
local filelist=$(mktemp)
# Collect atime, file size and file name of every file in the cache
find "$cache_dir" -type f -exec stat --printf "%X\t%s\t%n\n" "{}" \+ > "$filelist"
# Sort the files by access date (least recent first) and then file size (largest first)
sort -k1n -k2nr "$filelist" | while read atime fsize fname
do
# Get the directory of the file being deleted
local dir=${$(dirname "$fname")##$cache_dir}
# Add to the counts
deleted_bytes+=($dir $((${${deleted_bytes[$dir]}:-0} + $fsize)))
deleted_files+=($dir $((${${deleted_files[$dir]}:-0} + 1)))
# Delete the file
rm -f -- "$fname"
to_free=$(($to_free - $fsize))
if [ $to_free -lt 0 ]; then
break
fi
done
# Remove empty folders we may have left behind
find $cache_dir -type d -empty -delete
local sum_deleted=$((${(j:+:)deleted_bytes}))
local num_deleted=$((${(j:+:)deleted_files}))
local num_directories=${(w)#deleted_bytes}
printf "[%s] Done cleaning cache; deleted %d files in %d directories, totalling %d Bytes:\n" "$(date +"%F %T")" "$num_deleted" "$num_directories" "$sum_deleted" >> $logfile
# Print information about every directory we deleted files from
for directory_name in ${(ko)deleted_files}
do
printf "\t%s:\t\t%d file(s)\t\t%d Bytes\n" "$directory_name" "$deleted_files[$directory_name]" "$deleted_bytes[$directory_name]" >> $logfile
done
# All clear, we're done messing with the cache
killall -s SIGUSR2 polipo
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment