Last active
August 29, 2015 14:23
-
-
Save grubernd/74f8fb61544d9ce72e7c to your computer and use it in GitHub Desktop.
watch a folder for an inotify event and run a command
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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