skip to Main Content

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

2

Answers


  1. Chosen as BEST ANSWER

    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


  2. 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" --format '%w%f'
            ev=$?
        done
    }
    
    # Monitorizeaza modificarile
    while true; do
        inotifywait -r -e close_write "$WATCH_DIR" --format '%w%f'
        waitFor5SecondsSilence
        eval "$FILEBOT_CMD"
    done
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search