Created
June 15, 2025 20:26
-
-
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
This file contains hidden or 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 | |
| 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