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
Comments
-
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 about 12 yearsthis 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 about 11 yearsPlease 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 about 11 yearsBecause 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 about 11 yearsOk, 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 about 11 yearsi actually double checked the vote-down guidlines before posting my last comment.
-
VDR almost 11 yearsWell, 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 over 10 yearsI'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 over 8 yearsIn 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 almost 8 yearsI 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 about 7 yearsI really like the simplicity of this solution.