Skip to content

Instantly share code, notes, and snippets.

@grubernd
Last active August 29, 2015 14:23
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save grubernd/74f8fb61544d9ce72e7c to your computer and use it in GitHub Desktop.
Save grubernd/74f8fb61544d9ce72e7c to your computer and use it in GitHub Desktop.
watch a folder for an inotify event and run a command
#!/bin/bash
#-----------------------------------------------------------
# Copyright (C) 2015 GRUBERND http://grubernd.at
# released under a FreeBSD License
#
# watch a folder for an inotify event and run a command
# dependencies: inotify-tools
#--------------------------------------- Defaults
readonly version_hotfolder="15.06"
readonly this_program=$(basename $0)
readonly arguments="$@"
readonly default_settingsfilename="hot_settings"
#--------------------------------------- Help
help_short () {
# short version of help for the short -h argument
cat << 'HELPEND'
. . . Usage: hotfolder [-h | --help]
[-c | --create] [settingsfilename]
[-s | --settings <settingsfile>]>
filename of <settingsfile> can not contain stringbreaking whitespace!
HELPEND
}
help_long () {
# long version of help for the long --help argument
cat << 'HELPEND'
. . . Usage: hotfolder [-h | --help]
[-c | --create] [settingsfilename]
[-s | --settings <settingsfile>]>
-c | --create :: write a new default settingsfile, optional filename
-s | --settings :: run with settings from file
beware: filename <settingsfile> can not contain stringbreaking whitespace!
hotfolder watches for events in a folder and then executes a command.
all settings and the command are contained in a settingsfile.
if no such file is at hand it can be written by the script and
then should be edited to suite the job.
in the settingsfile there is a function command_block() which
should contain everything that should be done upon an event.
the variables in the settingsfile control the behaviour:
- watched_event sets the type of event that is being waited for.
please see "man inotifywait" for more details about events.
- watched_folder is the folder being watched recursively.
can be relative or absolute path.
important: ~/ will not be expanded. use $HOME/ instead.
- inotify_format sets what info gets send back to the command_block.
- hot_command sets the action taken. should not need adjustment.
HELPEND
}
# --------------------------------------
create_settingsfile () {
# to keep the script 100% selfcontained we have the option to create
# a default settingsfile from itself.
if [[ ! -f "$1" ]]; then
echo -e "writing hotfolder settingsfile with defaults: $1"
cat > "$1" << 'CREATEEND'
#!/bin/bash
# hotfolder settings file
command_block () {
# here goes everything you want to happen upon an event:
echo -e "argument 1 :: $1"
echo -e "argument 2 :: $2"
}
# various argument parts passed on, see "man inotifywait" for more details
watched_event="close_write"
watched_folder="$HOME/pictures/screenshots/" # do NOT use ~/
inotify_format="%w %f"
hot_command="command_block"
CREATEEND
else
echo -e "create ERROR: file already exists"
fi
}
# --------------------------------------
parse_arguments () {
# depending on arguments we run functions
# only correct args for -s|--settings keep the script on running
# all other cases stop the script after their action
# without arguments display a little help and stop
if [[ -z "$@" ]]; then
echo -e "hotfolder: missing arguments."
help_short
exit 1
fi
# work through the arguments
local i=
for i in "$@"; do
case $i in
-h) help_short
exit
;;
--help) help_long
exit
;;
-c | --create)
if [[ -n "$2" ]]; then
settingsfile="$2"
create_settingsfile "$2"
else
create_settingsfile "$default_settingsfilename"
fi
exit
;;
-s | --settings)
if [[ -n "$2" ]]; then
settingsfile="$2"
shift 2
continue
else
echo -e "ERROR: missing argument for settingsfile"
exit 1
fi
;;
*)
break
;;
esac
done
}
# --------------------------------------
get_settings () {
# include the settingsfile as part of the script or break on error
if [[ -f "$settingsfile" ]]; then
source "$settingsfile"
else
echo -e "settingsfile ERROR: $settingsfile is not a file."
exit 1
fi
}
check_settings () {
# break on various errors with helpful error messages
# those provided by inotifywait are somewhat cryptic
if [[ -z "$watched_event" ]]; then
echo -e "settingsfile ERROR: watched_event is not set"
exit 1
fi
if [[ ! -d "$watched_folder" ]]; then
echo -e "settingsfile ERROR: $watched_folder is not a folder"
exit 1
fi
if [[ -z "$hot_command" ]]; then
echo -e "settingsfile ERROR: hot_command is not set"
exit 1
fi
}
# --------------------------------------
inotify_loop () {
# this is where the real work happens
# if variables are replaced with actual values this works as a oneliner
# the rest of the script is just to help with the workflow
# TODO ?? put all arguments for inotifywait into the settingsfile ??
inotifywait --event "$watched_event" \
--monitor \
--recursive \
--quiet \
--format "$inotify_format" \
"$watched_folder" \
| while read this
do
# $this is NOT quoted so multiple params can be passed
$hot_command $this
done
}
# ---------------------------------------------------------- Main
# most arguments cause the script to stop somewhere in parse_arguments
# also get_ and check_settings contain conditional breakpoints
parse_arguments $arguments
get_settings
check_settings
echo -e "hotfolder - GRUBERND $version_hotfolder :: $settingsfile"
echo -e "press Ctrl-C to end.."
inotify_loop
# EOF
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment