0

I'm trying to make a FIFO script that keeps deleting files when disk usages reaches a limit. I have used the find command so that number of files wont be a limit to run the script. But I get an error

/share/capture/per.sh: line 13: find /share/capture/job1/ -type f -name "*.pcap": division by 0 (error token is "share/capture/job1/ -type f -name "*.pcap"")

The script I made is below:

#!/bin/bash

limit=10
#get usage percentage
per=$(df|grep '/dev/sdb.'|awk -F'[^0-9]*' '{print $5}')  
#get folders
dir=($(ls -d /share/capture/*/))
while [[ ${per} -gt $limit ]]
do
 for dirs in "${dir[@]}"; do
  files=(*)
  #get list of all pcap files in those folders 
  files=$((find $dirs -type f -name "*.pcap"))
  len="${#files[@]}"
  if [[ ${len} -gt $limit ]]
  then
   echo "${files[@]:0:10}"
   rm -f "${files[@]:0:10}" #delete 10 files
   fi
 done
#Update per
done
echo $per

The files are ordered with oldest coming on top of the array. Also any suggestion on how to run the script by interrupt rather than polling, i.e. every time a file is added to any of the folder in capture I would like to run the script.

I have modified the script to following:

   #!/bin/bash  
  limit=8
  file_limit=10
  per=$(df|grep '/dev/sdb.'|awk -F'[^0-9]*' '{print $5}')
  dir=($(ls -d /share/capture/*/))
  while [[ ${per} -gt $limit ]]
  do
  for dirs in "${dir[@]}"; do
   files=(*)
   files=($(find $dirs -type f -name "*.pcap"))
   len="${#files[@]}"
   if [[ ${len} -gt $file_limit ]]
   then
    echo "${files[@]:0:10}"
    rm -f "${files[@]:0:10}"
    fi
   done
   done
    echo $per

The error is solved, but the script tends to delete all files instead of just deleting enough to take usage percentage down to limit. Am I still doing something wrong?

  • 3
    The double-parentheses syntax $((find ...)) attempts to evaluate the expression arithmetically: perhaps you meant to write ($(find ...))? – steeldriver Jul 27 '15 at 14:09
  • @steeldriver yup, thats the reason. Thanks a bunch – Jishnu U Nair Jul 27 '15 at 14:15
2

Answering the second part of your question, the "best" way to watch for filesystem changes is by using inotify(7).

There is a set of utilities that can hook into the kernel interface, inotify-tools. In particular, you want inotifywait from that set of utilities:

inotifywait efficiently waits for changes to files using Linux's inotify(7) interface. It is suitable for waiting for changes to files from shell scripts. It can either exit once an event occurs, or continually execute and output events as they occur.

You could use it like this:

#!/bin/sh
while inotifywait -e create /share/capture/*/; do
  /share/capture/per.sh
done

You script will only then be called when a new file is created. I did not test the example - I adapted it from the manual page, so please adapt as needed.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.