Bash script, watch folder, execute command
I am trying to create a bash script with 2 parameters:
- a directory
- a command.
I want to watch the directory parameter for changes: when something has been changed the script should execute the command.
I'm running MacOS, not Linux; any pointers or external resources would greatly help as I have see that this is difficult to achieve. Really OI am trying to mimic SASS's watch functionality.
#!/bin/bash
#./watch.sh $PATH $COMMAND
DIR=$1
ls -l $DIR > $DIR/.begin
#this does not work
DIFFERENCE=$(diff .begin .end)
if [ $DIFFERENCE = '\n']; then
#files are same
else
$2
fi
ls -l $DIR > $DIR/.end
Solution 1:
To continuously recursively monitor folder (md5) and execute a command on change:
daemon() {
chsum1=""
while [[ true ]]
do
chsum2=`find src/ -type f -exec md5 {} \;`
if [[ $chsum1 != $chsum2 ]] ; then
if [ -n "$chsum1" ]; then
compile
fi
chsum1=$chsum2
fi
sleep 2
done
}
Works on my OS X as I do not have digest
.
On Linux, you can use md5sum
as a replacement for the md5
command.
Solution 2:
I can’t believe nobody posted this yet.
First make sure inotify-tools
are installed.
Then use them like this:
logOfChanges="/tmp/changes.log.csv" # Set your file name here.
# Lock and load
inotifywait -mrcq $DIR > "$logOfChanges" &
IN_PID=$$
# Do your stuff here
...
# Kill and analyze
kill $IN_PID
cat "$logOfChanges" | while read entry; do
# Split your CSV, but beware that file names may contain spaces too.
# Just look up how to parse CSV with bash. :)
path=...
event=...
... # Other stuff like time stamps?
# Depending on the event…
case "$event" in
SOME_EVENT) myHandlingCode path ;;
...
*) myDefaultHandlingCode path ;;
done
Alternatively, using --format
instead of -c
on inotifywait
would be an idea.
Just man inotifywait
and man inotifywatch
for more infos.
Solution 3:
Here's an example of watching a folder for changes and running a the less compiler when one is updated. As a prereq you need npm
and these the module onchange. The node community has a whole bunch of different watch commands (like onchange) I'm not aware of any that are compiled self-contained binaries.
npm install less onchange -g
Then you can use something like:
onchange "./stylesheets/*.less" -- lessc main.less > main.css
I prefer a BASH command over the Grunt answer I gave a while back.