Skip to content

Instantly share code, notes, and snippets.

@elecnix
Last active December 17, 2015 12:29
Delete old files until the disk usage target is reached. The objective is to keep the disk filled to a maximum value, while leaving some free space. The script was made to manage webcam images, and it always keep "snapshots", which are kept for very long time-lapses, and moved off the disk by an other script.
#!/bin/bash
function used_percent {
df -m "$MOTION_PATH" | tail -n 1 | sed -e 's/.* \(.*\)% .*/\1/'
}
function log {
echo "[$(date +%c)] $@"
}
MOTION_PATH="$1"
USED_PERCENT_TARGET=${USED_PERCENT_TARGET:-90}
declare -i MIN_DAYS_TO_KEEP=3
DRY_RUN=${DRY_RUN:-no}
declare -i USED_PERCENT
log "Pruning $MOTION_PATH to $USED_PERCENT_TARGET% of disk space."
log "Dry run: $DRY_RUN"
DELETE_ARG=""
if [ "$DRY_RUN" == "no" ] ; then
DELETE_ARG="-delete"
else
log "Running in dry-run mode."
fi
USED_PERCENT=$(used_percent)
if [ $USED_PERCENT -le $USED_PERCENT_TARGET ] ; then
log "Using $USED_PERCENT%, target is $USED_PERCENT_TARGET. Nothing to do."
exit 0
fi
log "Using $USED_PERCENT%, target is $USED_PERCENT_TARGET. Finding oldest file that can be pruned..."
PRUNABLE_PREDICATE=( "-type" "f" "-not" "-path" "*snapshot*.jpg" )
OLDEST=$(find $MOTION_PATH ${PRUNABLE_PREDICATE[@]} -printf "%T@ %P\n" | sort -nr | tail -1)
OLDEST_FILE=$(echo "$OLDEST" | cut -d' ' -f 1-)
declare -i OLDEST_TIMESTAMP=$(echo "$OLDEST" | cut -d'.' -f 1)
declare -i CURRENT_TIMESTAMP=$(date +%s)
declare -i OLDEST_SECONDS_AGO=$CURRENT_TIMESTAMP-$OLDEST_TIMESTAMP
declare -i OLDEST_DAYS_AGO=$OLDEST_SECONDS_AGO/86400
log "Oldest is $OLDEST_DAYS_AGO days old: $(date -d @${OLDEST_TIMESTAMP}) $OLDEST_FILE"
# Find files
declare -i DAYS_AGO=$OLDEST_DAYS_AGO
USED_PERCENT=$(used_percent)
while [ $DAYS_AGO -gt $MIN_DAYS_TO_KEEP ] && [ $USED_PERCENT -gt $USED_PERCENT_TARGET ] ; do
log "Disk usage is $USED_PERCENT%, target is $USED_PERCENT_TARGET. Deleting files $DAYS_AGO days old..."
find $MOTION_PATH "-mtime" "$DAYS_AGO" ${PRUNABLE_PREDICATE[@]} -print $DELETE_ARG
USED_PERCENT=$(used_percent)
DAYS_AGO=$DAYS_AGO-1
done
if [ $USED_PERCENT -le $USED_PERCENT_TARGET ] ; then
log "Using $USED_PERCENT%, target is $USED_PERCENT_TARGET. Done."
exit 0
else
log "Using $USED_PERCENT%, target is $USED_PERCENT_TARGET, and deleted files older than $DAYS_AGO days. Aborting."
exit 1
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment