Created
March 2, 2014 14:35
-
-
Save jtraulle/9307456 to your computer and use it in GitHub Desktop.
Simple Shell script to free-up space on disk based on least recently used files.
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 -u | |
#Jean Traullé <[email protected]> | |
#Under CC0 <http://creativecommons.org/publicdomain/zero/1.0/deed.fr> | |
#Default size is 20Mo | |
SIZE=20971520 | |
#Not in dryrun mode by default | |
DRYRUN=0 | |
#Not recursive by default | |
RECURSIVE="-maxdepth 1" | |
#Default void options | |
RESTRICTTOUSER= | |
FOLDERS= | |
USER= | |
EXTENSION= | |
CUMULATEDSIZE=0 | |
VERBOSE=0 | |
#Analysing options with getopts and defining variables | |
while getopts ":s:nRu:e:v" option | |
do | |
case $option in | |
s) | |
#Option argument need to be a number | |
PATTERN='^[0-9]+$' | |
if ! [[ $OPTARG =~ $PATTERN ]] | |
then | |
echo "Usage: -$option argument (size in bytes) must be a number" | |
exit 1 | |
fi | |
#Option argument need to be greater that 0 | |
if [ $OPTARG -eq 0 ] | |
then | |
echo "Usage: -$option argument (size in bytes) must be greater than 0" | |
exit 1 | |
fi | |
SIZE=$OPTARG | |
;; | |
u) | |
USER="-user ${OPTARG}" | |
;; | |
e) | |
#Option argument need to be alphanumeric | |
PATTERN='^[a-z]+$' | |
if ! [[ $OPTARG =~ $PATTERN ]] | |
then | |
echo "Usage: -$option argument (extension) must be alphanumeric" | |
exit 1 | |
fi | |
EXTENSION="-name *.${OPTARG}" | |
;; | |
v) | |
VERBOSE=1 | |
;; | |
R) | |
RECURSIVE= | |
;; | |
n) | |
DRYRUN=1 | |
;; | |
:) | |
echo "-$option option require argument" | |
exit 1 | |
;; | |
\?) | |
echo "Invalid -$OPTARG option" | |
exit 1 | |
;; | |
esac | |
done | |
#Deleting options and options arguments | |
shift $((OPTIND-1)) | |
#Script need to have at leat 1 arg | |
if [ $# -lt 1 ] | |
then | |
echo "Usage: pass at least one directory in argument." | |
exit 1 | |
fi | |
#Converting all path provided to absolute path | |
for dir in "$@" | |
do | |
if [ -d "$dir" ] | |
then | |
FOLDERS="${FOLDERS}$(readlink -f $dir) " | |
else | |
echo "mylru: ${dir} is not a directory" | |
exit 1 | |
fi | |
done | |
# Find all files | |
# - with write right (needed to delete file) | |
# - with size less that specified -s arg | |
# - redirect permission and other error messages to blackhole | |
# - exec option to get : | |
# - date of last access since epoch | |
# - size of file in bytes | |
# - path of file | |
# - we sort by asc last access date since epoch (after removing = outputed by stat command) | |
FINDRESULTS=$(find $FOLDERS $RECURSIVE $USER $EXTENSION -type f -writable -size -${SIZE}c 2> /dev/null -exec stat -c="%X:%s:%n" {} \; | cut -d= -f2 | sort -t: -k1n,1) | |
#If no result, print a message and quit | |
if [ -z "$FINDRESULTS" ] | |
then | |
echo "mylru: No file meet your criteria. Nothing to delete !" | |
exit 1 | |
fi | |
#Replacing Internal Field Separator by newline symbol after saving it | |
#to permit cycling through files paths (which contains spaces). | |
SAVEIFS=$IFS | |
IFS=$'\n' | |
echo "" | |
#For each founded file, extract epoch, size and path from line | |
for file in $FINDRESULTS | |
do | |
EPOCHFILE=$(echo "$file" | cut -d: -f1) | |
DATEFILE=$(date -d@"$EPOCHFILE" +%c) | |
FILESIZE=$(echo "$file" | cut -d: -f2) | |
FILEPATH=$(echo "$file" | cut -d: -f3-) | |
#If we do not exeed $SIZE, process for this file | |
#otherwise, we check the next file in the list. | |
if [ "$(expr ${CUMULATEDSIZE} + ${FILESIZE})" -lt "${SIZE}" ] | |
then | |
CUMULATEDSIZE=$(expr ${CUMULATEDSIZE} + ${FILESIZE}) | |
#If in Dryrun mode, do not delete the file | |
if [ "${DRYRUN}" -eq 1 ] | |
then | |
echo "${FILEPATH}" | |
else | |
rm "${FILEPATH}" | |
echo "rm ${FILEPATH}" | |
fi | |
#If user require verbose, print some useful info about the file | |
if [ "${VERBOSE}" -eq 1 ] | |
then | |
echo "${FILESIZE}B, last accessed on ${DATEFILE}" | |
echo "" | |
fi | |
fi | |
done | |
#Restoring IFS anterior value | |
IFS=$SAVEIFS | |
#Prints total scape freed and quit | |
echo -e "Total space freed ${CUMULATEDSIZE}B\n" | |
exit 0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment