Skip to content

Instantly share code, notes, and snippets.

@capocasa
Created October 19, 2020 12:35
Show Gist options
  • Save capocasa/134ce5312747e585a3e05cf70feebf7b to your computer and use it in GitHub Desktop.
Save capocasa/134ce5312747e585a3e05cf70feebf7b to your computer and use it in GitHub Desktop.
#!/bin/bash
### configuration section
BOUNCE_EXIT_CODE=72
RUN_SECONDS=4
LOCK_FILE_DIRECTORY="/dev/shm"
###
set -o errexit
if [ "$1" = "" ] || [ "$1" = "--help" ] || [ "$1" = "-h" ]; then
echo "Usage: $(basename $0) [command]
Generic debounce in bash. Waits for $RUN_SECONDS seconds and runs the provided command.
If the same command is run from another shell, the shell exits with a code of $BOUNCE_EXIT_CODE,
and the wait time is set to $RUN_SECONDS from the time the second command is executed. This means
that only the first call of the command will run, but it will be delayed until the command was not
called again for $BOUNCE_EXIT_CODE seconds. This is process is called "debouncing".
The resolution is seconds. The command may contain spaces and escape characters. No processes are
killed during the execution of the script. A timestamp is written for every call of the script.
Lock file location and wait time can be configured by editing the top of the script."
exit 1
fi
HASH=$(echo -n '%s' "$@" | md5sum | head -c 32)
LOCK_FILE="$LOCK_FILE_DIRECTORY/debounce-sh-$HASH"
CURRENT_TIME=$(date +%s)
let RUN_TIME=CURRENT_TIME+3
if [ -f "$LOCK_FILE" ]; then
if [ $(<$LOCK_FILE) -lt $CURRENT_TIME ]; then
# clear stale file and continue as if it hadn't been there
rm -f $LOCK_FILE
else
# this is a bounce, bump run time and exit with bounce return code
echo $RUN_TIME > "$LOCK_FILE"
exit $BOUNCE_EXIT_CODE
fi
fi
# This is a run.
# Store run time in a place where it can be changed by other instances of this script.
echo $RUN_TIME > "$LOCK_FILE"
# Wait for run time. It could be the one set by this instance, or by other, bounced, instances
while [ $(date +%s) -lt $(<$LOCK_FILE) ]; do
sleep 1
done
# cleanup, run and exit
rm -f $LOCK_FILE
exec $@
@clintwood
Copy link

Nice - except I believe you need to change line 29 to actually use RUN_SECONDS instead of the hard-coded 3 seconds:

let RUN_TIME=CURRENT_TIME+RUN_SECONDS

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment