Skip to content

Instantly share code, notes, and snippets.

@avhm
Created June 15, 2025 20:26
Show Gist options
  • Select an option

  • Save avhm/5be83a3461be063ddbc3fc947c340d55 to your computer and use it in GitHub Desktop.

Select an option

Save avhm/5be83a3461be063ddbc3fc947c340d55 to your computer and use it in GitHub Desktop.
Shell script to trigger a plex library scan when files in the provided paths change. Debounced, Synology NAS compatible
#!/bin/bash
set -euo pipefail
###############################################################################
WATCH_DIRS=(/volume1/TV /volume1/Movies)
MIN_BYTES=104857600 # Minimum file size trigger
EX_RE='.*(\.part|\.!qB|\.!ut)$'
INO=$(command -v inotifywait)
FLOCK=$(command -v flock)
DEBOUNCE=20 # seconds
PLEX_HOST='plex.server.com'
PLEX_TOKEN='xxxxxxxxxxxxxxxxxxxx'
LOG=/volume1/Anthony/scripts/watch.log
TMP=/tmp/.plex.batch # holds paths in the current batch
###############################################################################
mkdir -p "$(dirname "$LOG")"
exec >>"$LOG" 2>&1
echo "--- watcher (pid $$) started $(date '+%F %T') with debounce=${DEBOUNCE}s ---"
refresh() {
# Build a label: first file name (basename) + count
if [[ -s $TMP ]]; then
mapfile -t paths <"$TMP"
n=${#paths[@]}
first=$(basename "${paths[0]}")
label=$first
(( n > 1 )) && label="${first%.*} …"
echo "[refresh] ${n} new file(s) (${label}) after ${DEBOUNCE}s quiet"
: >"$TMP" # clear batch list
else
echo "[refresh] triggered with no path info"
fi
curl -s "http://${PLEX_HOST}:32400/library/sections/all/refresh?X-Plex-Token=${PLEX_TOKEN}" \
--output /dev/null
}
"$INO" -m -r --quiet -e close_write,move --format '%w%f' "${WATCH_DIRS[@]}" |
while read -r p; do
[[ $p =~ $EX_RE ]] && continue
(( $(stat -c%s "$p" 2>/dev/null || echo 0) < MIN_BYTES )) && continue
echo "$p" >>"$TMP" # remember for log
touch /tmp/.plex.hit # (re)arm the timer
if [[ -n $FLOCK ]]; then
(
"$FLOCK" -x 200 || exit
sleep "$DEBOUNCE"
if (( $(date +%s) - $(stat -c%Y /tmp/.plex.hit) >= DEBOUNCE )); then
refresh
fi
) 200>/tmp/.plex.lock &
else
refresh
fi
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment