Search code examples
bashwhile-loopinotifydetach

Bash: Jump to the next iteration of a while loop without waiting for the command in the loop to exit


I am trying to write a little script which does the following:

  1. Launch the PDF slideshow viewer impress!ve which can display all PDF files inside a folder page after page in a slideshow.
  2. Watch the folder for changes (adding or deleting files).
  3. On change, restart the viewer to pick up the modified folder contents.
  4. Continue watching the folder for changes.

So far it looks like this:

#!/bin/bash

TESTPATH="/some/path/"

while true; do
    inotifywait -e create,delete,moved_from -r "$TESTPATH" && \
        echo "DEBUG: Event detected!" && pkill -f /usr/bin/impressive || true && impressive -a 10 -w "$TESTPATH*.pdf"
done

However I am stuck with the following issue: Once impressive has been started for the first time, it is being executed permanently and the loop is stuck inside this first iteration and inotifywait won't continue monitoring till impressive isn't killed by hand. I'd like to jump to the next iteration of the while loop directly after the launch of impressive, without waiting for it to exit.

I tried putting a nohup in front of the impressive call but it lead to my RAM getting full in a second and my machine freezing...

How can I solve this issue?

Solution thanks to hints by Barmar and Fravadona:

#!/bin/bash

TESTPATH="/some/path/"

inotifywait -m "$TESTPATH" -e moved_to -e moved_from -e delete |
    while read -r directory action file; do
            {
                echo "DEBUG: Event detected!" && pkill -f /usr/bin/impressive || true && impressive -a 10 -w "$TESTPATH*.pdf" &
            }
    done

Solution

  • You might want to run the impressive command asynchronously. And did you know that you can group commands in curly-brackets?

    #!/bin/bash
    
    TESTPATH="/some/path/"
    
    while true
    do
        inotifywait -e create -e delete -e moved_from -r "$TESTPATH" && {
            echo "DEBUG: Event detected!"
            kill %
            impressive -a 10 -w "$TESTPATH"*.pdf &
        }
    done
    

    remark: I constrained the kill to the impressive process of the previous iteration, and moved the glob out of the double-quotes (for it to get expanded)