Bash script to delete files until directory size is less than X

I am trying to write a script to remove files from a folder (/ home / folder) until the size of the home directory (/ home /) is less than X GB. The script should delete 25 files at a time and they should be the oldest in the directory. However, I am noob and I could not think of a loop. Instead, I wrote the same script lines below several times; it works, but I would like the loop to be better. Could you please help me with a more elegant, efficient way?

size=$(du -shb /home/ | awk '{print $1}')
if [ "$size" -gt X ]; then
find /home/folder -maxdepth 1 -type f -printf '%T@\t%p\n' | sort -r | tail -n 25 | sed 's/[0-9]*\.[0-9]*\t//' | xargs -d '\n' rm -f
sleep 30
else
exit
fi

      

+3


source to share


2 answers


Not bad! The easiest way to do it in a loop is to simply add an infinite loop to it. The exit output will exit the script and obviously so also the loop:

while true
do
  size=$(du -shb /home/ | awk '{print $1}')
  if [ "$size" -gt X ]; then
    find /home/folder -maxdepth 1 -type f -printf '%T@\t%p\n' | sort -r | tail -n 25 | sed     's/[0-9]*\.[0-9]*\t//' | xargs -d '\n' rm -f
    sleep 30
  else
    exit  # <- Loop/script exits here
  fi
done

      

You can also rewrite the logic to make it look nicer:



while [ "$(du -shb /home/ | awk '{print $1}')" -gt X ]
do
  find /home/folder -maxdepth 1 -type f -printf '%T@\t%p\n' | \
      sort -n | head -n 25 | cut -d $'\t' -f 2-  | xargs -d '\n' rm -f
done

      

And you can also overwrite it without repeating /home

over and over, thus allowing you to delete individual files instead of 25 blocks:

usage=$(du -sb /home | cut -d $'\t' -f 1)
max=1000000000
if (( usage > max ))
then
  find /home/folder -maxdepth 1 -type f -printf '%T@\t%s\t%p\n' | sort -n | \
    while (( usage > max )) && IFS=$'\t' read timestamp size file
    do
      rm -- "$file" && (( usage -= size ))
    done
fi

      

+3


source


If you are looking for a BusyBox compatible script:



DIRECTORY=$1
MAX_SIZE_MB=$2
KB_TO_MB=1000
MAX_SIZE_KB=$(($MAX_SIZE_MB*$KB_TO_MB))

if [ ! -d "$DIRECTORY" ]
then
  echo "Invalid Directory: $DIRECTORY"
  exit 1
fi

usage=$(du -s $DIRECTORY | awk '{print $1}')
echo "$DIRECTORY - $(($usage/$KB_TO_MB))/$MAX_SIZE_MB MB Used"
if (( usage > $MAX_SIZE_KB ))
then
    #https://stackoverflow.com/questions/1447809/awk-print-9-the-last-ls-l-column-including-any-spaces-in-the-file-name
    files=($(find $DIRECTORY -maxdepth 1 -type f -print| xargs ls -lrt | sed -E -e 's/^([^ ]+ +){8}//'))
    for file in ${files[@]};
    do
        size=$(du -s "$file" | awk '{print $1}')
        rm -f "$file"
        ((usage -= size))
        if (( $usage < $MAX_SIZE_KB ))
        then
           break
        fi  
    done
fi

      

0


source







All Articles