Quickly generate a list of photos with feh and some shell scripts
This post is mainly an illustration of how to be productive while having fun, all of that in the Unix spirit :)
Recently I found myself needing to go through my photos and select some of them for later processing. I wanted to generate a file containing a list of the file names, and after starting writing the names manually in nano
for a few pictures, I decided to find a more efficient way to do this.
# Enter actions in feh
I use feh to view my photos. It's simple and it does exactly what I want: display my photos on my screen, without useless bells and whistles. Well actually, it does much more than that, still without any bell or whistle.
Taking a look at man feh
, I could see that there is a lot more I could do with this program. I already had some custom settings enabled in the rifle.conf
of ranger, my file manager, such as -F
for fullscreen mode, -x
for borderless, --keep-zoom-vp
to keep the zoom and viewport when switching between photos, -d
to show the filename at the top left corner of the window, --auto-rotate
.
In the very long man page, you can find the actions
section. You can assign, by passing --action "shell command"
, a shell command to execute when pressing enter. If it's not enough, you can ever specify up to 9 supplementary actions with the --actionN
argument.
This allowed me to very easily assign a shell script that would do what I want: add or remove a file from my file list.
I added --action "add_photo_to_list %F"
to my rifle.conf
's feh entry,
and created this script named add_photo_to_list to my $PATH :
#!/bin/sh
dest=~/Documents/photo_list.txt
if grep -q "$1" "$dest"; then
sed -i '/'"$1"'$/d' "$dest"
else
echo "$1" >> "$dest"
fi
This script takes the file path as argument (%F
from feh), and does one of two things:
- if the file was found in my photo_list.txt, remove it with sed:
-i
for in-place modification, and/^filename$/d
for deleting lines containingfilename
. - otherwise, add it at the end of photo_list.txt
This way, every time I hit enter, the file gets either added or removed from the list.
I used watch "tail -n 50 photo_to_order.txt"
to monitor the list and checking that everything was running well. sometimes I changed my mind and came back to a photo to remove it from the list, and I checked that I didn't do any mistake in the photos by checking the file list.
It was not exactly as smooth as I wanted it to be, so I decided to add a little bit of feedback to the process.
# Bells and Whistles
I had this script in my $PATH to play some sounds from PulseAudio, I use it for generating alerts for various things, such as email or low battery notification:
#!/bin/sh
which=$1
n=$2
USER_NAME=$(w -hs | awk -v vt=tty$(sudo -u root fgconsole) '$0 ~ vt {print $1}')
USER_ID=$(id -u "$USER_NAME")
export PULSE_SERVER="unix:/run/user/"$USER_ID"/pulse/native"
while [ $n -gt 0 ];do
pactl --server "$PULSE_SERVER" play-sample $which
let 'n--'
if [[ $n -gt 0 ]]; then
sleep .82
fi
done
This takes the name of the sound to play and a number of repetitions as arguments, there are a few hacky commands that I needed to get the script working from fcron
entries.
it plays the sound the desired amount of time with a short sleep between each.
The sounds should have been previously imported with pactl upload-sample "path-to-sound-file"
(put it in the ~/.xinitrc for example)
Having this already set up, I could just add:
#!/bin/sh
dest=~/Documents/photo_list.txt
if grep -q "$1" "$dest"; then
alert_sound Error 1
sed -i '/'"$1"'$/d' "$dest"
else
alert_sound Purr 1
echo "$1" >> "$dest"
fi
This way, every time I add a file, I get a satisfactory audio feedback and I am sure that my photo list was correctly updated :).
This whole setup took about 5 minutes of my time, and allowed me to be way faster in my photo selection process, and to make the task absolutely enjoyable as I was just navigating through my photos with the arrow keys, and toggling the presence of a photo in the list by pressing enter.
This is a really good example of why I love linux, and why investing time in understanding shell scripting and a few things of how my system works is proving useful for a lot of my daily tasks :)