PickOne
PickOne

Reputation: 37

How to make "inotifywait" run only once, after 5 seconds passed from all events detected

A little help, please, with this script:

#!/bin/bash

WATCH_DIR="/home/media/Movies"

# Comanda FileBot
FILEBOT_CMD="filebot -rename -r -non-strict \"$WATCH_DIR\" --db TheTVDB --format \"{n}/Season {s}/{n} - {s00e00} - {t}\" --action move --order Airdat"

# Monitorizeaza modificarile
inotifywait -m -r -e close_write "$WATCH_DIR" --format '%w%f' |
while read file; do
    echo "New Change: $file"
    eval $FILEBOT_CMD
done

This script detects if a file is opened to write (modify) and when a file is closed from writing (close_write), it is all good, it is working, but I want the script to be loaded only after all files finished, after no other event triggered for 5 seconds. Any solution to this?

So, if I copy 5 files, I don't want the script run 5 times, instead, I want the script to wait till all the files has finished the copy process, then run only once. Detect if no event triggered for 5 seconds, then run the action filebot only once... This should happens no matter what size the files have.

Thank you in advance

Upvotes: -2

Views: 98

Answers (2)

Ted Lyngmo
Ted Lyngmo

Reputation: 117168

One way would be to not use monitoring mode (-m) but instead let inotifywait exit when a single event happens, then reinvoke inotifywait with a 5 second timeout using the -t option and check the exit status. It'll exit with 0 if an event happened and 2 if it timed out (and 1 for error). Your monitoring script could then just loop to repeat the procedure.

Example:

waitFor5SecondsSilence() {
    local ev=0
    while [[ $ev -eq 0 ]]; do
        inotifywait -t 5 -r -e close_write "$WATCH_DIR"
        ev=$?
    done
}

# Monitorizeaza modificarile
while true; do
    inotifywait -r -e close_write "$WATCH_DIR"
    waitFor5SecondsSilence
    eval "$FILEBOT_CMD"
done

An alternative could use monitoring mode together with a timeout when waiting for 5 seconds of no events:

# Monitorizeaza modificarile
while true; do
    inotifywait -r -e close_write "$WATCH_DIR"
    inotifywait -m -t 5 -r -e close_write "$WATCH_DIR"
    eval "$FILEBOT_CMD"
done

Upvotes: 1

PickOne
PickOne

Reputation: 37

I think that I have done the proper script for what I wanted to achieve...

#!/bin/bash

WATCH_DIR="/home/media/Movies"
DELAY=20
LAST_EVENT_TIME=0

# FileBot Command
FILEBOT_CMD="filebot -rename -r -non-strict \"$WATCH_DIR\" --db TheTVDB --format \"{n}/Season {s}/{n} >

# All done function
finalize_process() {
    CURRENT_TIME=$(date +%s)
    if (( CURRENT_TIME - LAST_EVENT_TIME >= DELAY )); then
        echo "All done, running script!"
       # eval $FILEBOT_CMD
    fi
}

# Monitor
inotifywait -m -r -e close_write --format '%w%f' "$WATCH_DIR" | while read -r file; do
    # Current timestamp
    EVENT_TIME=$(date '+%Y-%m-%d %H:%M:%S')

    # Echo for each event
    echo "Change detected for $file at $EVENT_TIME"

    # Last event time
    LAST_EVENT_TIME=$(date +%s)

    # Update past final message if exists
    if [[ -n "$finalization_pid" && -e /proc/$finalization_pid ]]; then
        kill $finalization_pid
    fi

    # Wait 20 seconds end verify the ending process
    (
        sleep "$DELAY"
        finalize_process
    ) &
    finalization_pid=$!
done

This script shows me an echo after every trigger, then waits 20 seconds and if there is no other trigger, it will fire a final echo with an optional command...

If someone have an optinion about this script, how to optimize it more, or if there could be a different approach, a better one, please share it.

About the double trigger "issue" with inotifywait, I made more tests and if I monitor the folder with "inotifywait -m", for event "close_write", it is acting a bit strange. Lets say that I will copy 5 files (file 1, 2, 3, 4, 5). I will get the echo for every trigger of finished file, but after 12-15 seconds of the "file 1" trigger, it will show the same trigger again. For a better exlpication, i will show you a result echos by copying 5 files:

Jan 01 23:23:48 mediaserver auto_filebot.sh[4275]: Watches established.
Jan 01 23:24:12 mediaserver auto_filebot.sh[4276]: Change detected for /home/media/Movies/test/Episode 1.mkv at 2025-01-01 23:24:12
Jan 01 23:24:17 mediaserver auto_filebot.sh[4276]: Change detected for /home/media/Movies/test/Episode 2.mkv at 2025-01-01 23:24:17
Jan 01 23:24:22 mediaserver auto_filebot.sh[4276]: Change detected for /home/media/Movies/test/Episode 3.mkv at 2025-01-01 23:24:22
Jan 01 23:24:26 mediaserver auto_filebot.sh[4276]: Change detected for /home/media/Movies/test/Episode 1.mkv at 2025-01-01 23:24:26
Jan 01 23:24:28 mediaserver auto_filebot.sh[4276]: Change detected for /home/media/Movies/test/Episode 4.mkv at 2025-01-01 23:24:28
Jan 01 23:24:32 mediaserver auto_filebot.sh[4276]: Change detected for /home/media/Movies/test/Episode 5.mkv at 2025-01-01 23:24:32
Jan 01 23:24:52 mediaserver auto_filebot.sh[4361]: All done, running script!

Any idea why inotifywait doubles the first trigger after 12-15 seconds?

Thank you for the help

Upvotes: 0

Related Questions