#!/bin/bash set -euo pipefail DIRECTORY=$1 FORCE=${2-false} JUST_DO_IT=${3-x} I_MEAN_IT=${4-x} LIMIT=10000000000 # 10GB ACTION=print #delete #LIMIT=13000000 # 13MB #ACTION=print MB1=1000000 estimate(){ find "$1" -type f -"$2" +"$3" ${4-} -print0 | du -cb --files0-from=- | grep total | cut -d' ' -f1 } cleanup(){ filter="$1" unit="${2-}" tmin="${3-}" echo "Deleting files greater than ${WEIGHT}${unit} ($filter)$(if [ -n "$tmin" ]; then echo " where $tmin"; fi) ..." find "$DIRECTORY" -type f -"$filter" +"${WEIGHT}${unit}" ${tmin} -"$ACTION" } search(){ upper="$3" lower="$2" filter="$1" unit="${4-}" tmin="${5-}" if [ "$unit" = "c" ]; then res=500000 elif [ "$filter" = "mmin" ]; then res=3 else res=0 fi WEIGHT="$lower" while (( upper - lower > res)); do echo "Finding files greater than ${WEIGHT}${unit} ($filter)$(if [ -n "$tmin" ]; then echo " where $tmin"; fi) ..." RECLAIM=$(estimate "$DIRECTORY" "$filter" "${WEIGHT}${unit}" "${tmin}") if (( SIZE - RECLAIM > LIMIT )); then upper="$WEIGHT" WEIGHT=$(((WEIGHT + lower)/2)) if (( WEIGHT == upper )); then break; fi if (( WEIGHT == lower )) && [ "$lower" != "$2" ]; then break; fi else lower="$WEIGHT" WEIGHT=$(((upper + WEIGHT)/2)) if (( WEIGHT == lower )) || (( WEIGHT == upper )); then break; fi fi done } summary() { SIZE=$(find "$DIRECTORY" -type f -print0 | du -cb --files0-from=- | grep total | cut -d' ' -f1) echo "Current size is : $((SIZE/MB1)) MB" } RECLAIM=0 declare WEIGHT SIZE summary echo "Size limit is : $((LIMIT/MB1)) MB" # nothing to do if (( SIZE < LIMIT )); then exit 0; fi trap 'summary' EXIT echo "Need to reclaim : $(( (SIZE - LIMIT)/MB1 )) MB" search mtime 30 365 if (( WEIGHT > 30 )); then cleanup mtime && exit 0; fi echo "Looking for big fat blobs older than 7 days and bigger than $((LIMIT/10/MB1))M ..." search size $((LIMIT/10/MB1)) $((LIMIT/MB1)) M "-mtime +7" if (( WEIGHT > LIMIT/10/MB1 )); then cleanup size M "-mtime +7" && exit 0; fi # avoid deleting young files if ! "$FORCE"; then echo "Refusing to cleanup files smaller than $((LIMIT/10/MB1))M and younger than 30 days"; exit 1; fi search mtime 7 30 if (( WEIGHT > 7 )); then cleanup mtime && exit 0; fi echo "Looking for big blobs older than 1 day and bigger than $((LIMIT/100/MB1))M ..." search size $((LIMIT/100/MB1)) $((LIMIT/MB1)) M "-mtime +1" if (( WEIGHT > LIMIT/100/MB1 )); then cleanup size M "-mtime +1" && exit 0; fi # avoid deleting very young files if [ "$JUST_DO_IT" != "JUST_DO_IT" ]; then echo "Refusing to cleanup files smaller than $((LIMIT/100/MB1))M and younger than 7 days"; exit 1; fi search mtime 0 7 if (( WEIGHT > 0 )); then cleanup mtime && exit 0; fi search mmin $((60*24)) $((60*24*2)) if (( WEIGHT > 60*24 )); then cleanup mmin && exit 0; fi echo "Looking for blobs older than 12 hours and bigger than $((LIMIT/1000/MB1))M ..." search size $((LIMIT/1000/MB1)) $((LIMIT/MB1)) M "-mmin +$((60*12))" if (( WEIGHT > LIMIT/1000/MB1 )); then cleanup size M "-mmin +$((60*12))" && exit 0; fi # avoid deleting ultra young files if [ "$I_MEAN_IT" != "I_MEAN_IT" ]; then echo "Refusing to cleanup files smaller than $((LIMIT/1000/MB1))M and younger than 1 day"; exit 1; fi search mmin 1 $((60*24)) cleanup mmin