linux script that monitors file changes within folders (like autospec does!)

35,792

Solution 1

After reading replies to other posts, I found a post (now gone), I created this script :-

#!/bin/bash

sha=0
previous_sha=0

update_sha()
{
    sha=`ls -lR . | sha1sum`
}

build () {
    ## Build/make commands here
    echo
    echo "--> Monitor: Monitoring filesystem... (Press enter to force a build/update)"
}

changed () {
    echo "--> Monitor: Files changed, Building..."
    build
    previous_sha=$sha
}

compare () {
    update_sha
    if [[ $sha != $previous_sha ]] ; then changed; fi
}

run () {
    while true; do

        compare

        read -s -t 1 && (
            echo "--> Monitor: Forced Update..."
            build
        )

    done
}

echo "--> Monitor: Init..."
echo "--> Monitor: Monitoring filesystem... (Press enter to force a build/update)"
run

Solution 2

Take a look at incron and inotify-tools.

Solution 3

keywords are inotifywait & inotifywatch commands

Solution 4

How about this script? Uses the 'stat' command to get the access time of a file and runs a command whenever there is a change in the access time (whenever file is accessed).

#!/bin/bash
while true
do
   ATIME=`stat -c %Z /path/to/the/file.txt`
   if [[ "$ATIME" != "$LTIME" ]]
   then
       echo "RUN COMMNAD"
       LTIME=$ATIME
   fi
   sleep 5
done

Solution 5

See this example as an improvement upon on Ian Vaughan's answer:

#!/usr/bin/env bash
# script:  watch
# author:  Mike Smullin <[email protected]>
# license: GPLv3
# description:
#   watches the given path for changes
#   and executes a given command when changes occur
# usage:
#   watch <path> <cmd...>
#

path=$1
shift
cmd=$*
sha=0
update_sha() {
  sha=`ls -lR --time-style=full-iso $path | sha1sum`
}
update_sha
previous_sha=$sha
build() {
  echo -en " building...\n\n"
  $cmd
  echo -en "\n--> resumed watching."
}
compare() {
  update_sha
  if [[ $sha != $previous_sha ]] ; then
    echo -n "change detected,"
    build
    previous_sha=$sha
  else
    echo -n .
  fi
}
trap build SIGINT
trap exit SIGQUIT

echo -e  "--> Press Ctrl+C to force build, Ctrl+\\ to exit."
echo -en "--> watching \"$path\"."
while true; do
  compare
  sleep 1
done
Share:
35,792
Ian Vaughan
Author by

Ian Vaughan

http://twitter.com/IanVaughan

Updated on July 10, 2022

Comments

  • Ian Vaughan
    Ian Vaughan almost 2 years

    I want to automatically kick off a build whenever a file changes.

    I've used autospec (RSpec) in Ruby and loved that.

    How can this be done in bash?

  • kritzikratzi
    kritzikratzi about 12 years
    this is the most horrible solution. it will raed all files from a directory every second which is a huge performance hit. please look at the solution by dennis williamson!!!
  • Ian Vaughan
    Ian Vaughan about 11 years
    Please remove your downvotes from my answers, they are valid answers and work, just because they are not acceptable for your usage, they have been fine for mine, and possibly other people as well. Thus downvoting means others will not try this answer. Downvotes are really only for things that do not work at all or are off topic etc. And also please edit your comments removing the word horrible, its a personal option of yours, you're welcome to say its not performance hit, but leave it at that. Cheers.
  • kritzikratzi
    kritzikratzi about 11 years
    Because something works does not mean it's a good idea to do it. In my opinion your answer is equally trivial and problematic. I see no reason to remove my downvote.
  • Ian Vaughan
    Ian Vaughan about 11 years
    Ok, its your call, whatever you choose, but may I point out stackoverflow.com/privileges/vote-down "Use your downvotes whenever you encounter an egregiously sloppy, no-effort-expended post, or an answer that is clearly and perhaps dangerously incorrect.". I would argue that its not sloppy nor no-effort-expended, and its certainly not dangerously incorrect. If you still believe otherwise, than thats fine, thanks.
  • kritzikratzi
    kritzikratzi about 11 years
    i actually double checked the vote-down guidlines before posting my last comment.
  • VDR
    VDR almost 11 years
    Well, we can use stat command to access/monitor DIR access time also: stat -c %Z /var/tmp script triggers whenever there is any addition or deletion in the DIR
  • NateDSaint
    NateDSaint over 10 years
    I'm going to do some performance testing on this solution, I think I worked somewhere that did something similar, and I feel like it's not that terrible of a hit, but everything is relative.
  • nealmcb
    nealmcb over 8 years
    In particular, see github.com/tartley/rerun2 which uses inotify-tools and makes it easy to run a custom command, as explained in Jonathan Hartley's overlooked answer on superuser
  • MilMike
    MilMike almost 8 years
    I know it is not optimal solution but on some systems you can't use or install inotify but you have a shell... in this case we can should anything that works. Thanks Ian!
  • Richard
    Richard about 7 years
    I really like the simplicity of this solution.