Search code examples
bashshellslideshowwatchinotify

Bash script for a slideshow with image list refresh


I'm writing a short script for a slideshow using fbi. For sake of completeness, the script gets executed after an automatic login on an Ubuntu machine, which should run headless; the machine only external interface should be a Samba folder where I add/remove images. I started easy:

usr/bin/fbi -noverbose -a -t 4 -u `find -type f | egrep -i "(jpg|bmp|png|gif)$"`

This works fine: find/egrep return a list of files that fbi shows at 4 seconds interval. Now, I need to refresh my slide list when a new image gets added or an existing one gets deleted. I tried watch, without success.

If I execute from command line this:

watch -n 300 -t `find -type f | egrep -i "(jpg|bmp|png|gif)$"`

I get the same list of files and whenever I add an image to my target folder, the list gets updated within next 5 minutes. Fine. But when I add this to my script, nothing works:

/usr/bin/fbi -noverbose -a -t 4 -u `watch -n 300 -t 'find -type f | egrep -i "(jpg|bmp|png|gif)$"'`

With this, I get nothing and when I interrupt the slideshow, my command line is screwed (no carriage return, no typing echo...).

What am I doing wrong/overlooking/missing? Or am I completely off target?

Because another solution would be to have two scripts, the slideshow's one and a controller script (maybe using inotify-tools), killing and restarting the slideshow script when target folder gets modified.

Any suggestion or tip, veeeery appreciated!

rash*


Solution

  • watch -n 300 -t `find -type f | egrep -i "(jpg|bmp|png|gif)$"`
    

    What this is doing, because you've used backticks, is passing the list of filenames to watch, which I suspect you don't want to do. Maybe this would work, but I don't have any way to test:

    watch -n 300 -t '/usr/bin/fbi -noverbose -a -t 4 -u `find -type f | egrep -i "(jpg|bmp|png|gif)$"`'
    

    Though this brings up the thorny question of just how many copies of fbi will be running after a few days.

    Probably your best bet would be to set up a cron job to run a script like this every x minutes:

    #!/bin/bash
    pkill -f /usr/bin/fbi
    shopt globstar
    cd /your/images/directory
    files=(**/*.jpg **/*.bmp **/*.png **/*.gif)
    usr/bin/fbi -noverbose -a -t 4 -u "${files[@]}"
    

    Instead of using find and grep, I used bash globbing, which is safe for filenames with spaces, and also saves you running two other commands! This requires bash 4+ for the globstar option that provides recursive matching.

    The globbing gives you file names in an array, which is passed directly to fbi, as described in Bash FAQ 50