macosbashterminalfswatch

Any script to notify when there is no write activity in folder


I am trying to come up with a nice and easy way of detecting when there has not been any write activity in a folder I'd like to watch.

Basically, what I'd like to have is something like this:

#!/bin/sh

# colored red text (error)
function errorMsg () {
  echo '\033[0;31m'"$1"'\033[0m'
}

# check for folder to monitor argument
if [ "$#" -ne 1 ]
then
  errorMsg "add experiment (folder) to monitor for activity!"
exit
fi

# time out time, 3 minutes
TIMEOUT_TIME=180
LAST_CHECKED=0

function refreshTimer () {
  # when called, check seconds since epoch
  CURRENT_TIME=date +%s

  if [ CURRENT_TIME - LAST_CHECKED > TIMEOUT_TIME ]
  then
    echo "file write activity halted!" | mail -s "trouble!" "user@provider.ext"
  fi

  LAST_CHECKED=date +%s
}

# set last checked to now.
LAST_CHECKED=date +%s
# start monitoring for file changes, and update timer when new files are being written.
fswatch -r ${1} | refreshTimer

but all sorts of bash magic is required I presume, since fswatch is a background task and piping its output creates a subshell. I would also be in need of some timer logic... I was thinking something like a setTimeout of which the time argument keeps being added to when there IS activity, but I don't know how to write it all in one script.

Bash, Python, Ruby, anything that can be installed using homebrew on OSX is fine but the simpler the better (so I understand what is happening).


Solution

  • Try the following - note that it requires bash:

    #!/usr/bin/env bash
    
    # colored red text (error)
    function errorMsg () {
      printf '\033[0;31m%s\033[0m\n' "$*" >&2
    }
    
    # check for folder to monitor argument
    if [[ $# -ne 1 ]]
    then
      errorMsg "add experiment (folder) to monitor for activity!"
      exit 2
    fi
    
    # time-out: 3 minutes
    TIMEOUT_TIME=180
    
    # Read fswatch output as long as it is
    # within the timeout value; every change reported
    # resets the timer.
    while IFS= read -t $TIMEOUT_TIME -d '' -r file; do 
      echo "changed: [$file]"
    done < <(fswatch -r -0 "${1}")
    
    # Getting here means that read timed out.
    echo "file write activity halted!" | mail -s "trouble!" "user@provider.ext"
    

    As for your original code:

    Note: Some of the problems discussed could have been detected with the help of shellecheck.net