1

I have this script which processes images in subfolders on Ubuntu 22.04 with exiftool 12.57:

#!/bin/bash

set -e

DIR=/path/to/photos

for f in $(find "${DIR}" -type f -iname "*.jpg" -o -iname "*.jpeg" -o -iname "*.png");
do
  echo "processing ${f}..."
  exiftool "${f}" >> output.txt
  printf -- '#%.0s' {1..80} >> output.txt
  printf '\n' >> output.txt
done

But it simply stops without throwing any warning or error to stdout/stderr when it reaches an empty file:

$ tail output.txt 
################################################################################
ExifTool Version Number         : 12.57
File Name                       : 20222601_DSC00057.JPG
Directory                       : /path/to/photos/experiment 11
File Size                       : 0 bytes
File Modification Date/Time     : 2020:10:26 15:03:22+01:00
File Access Date/Time           : 2023:03:02 16:47:51+01:00
File Inode Change Date/Time     : 2023:03:02 15:07:08+01:00
File Permissions                : -rw-rw-r--
Error                           : File is empty

The file is indeed a 0 byte file:

$ ls -larth /path/to/photos/experiment\ 11/20222601_DSC00057.JPG
-rw-rw-r-- 1 1000 1000 0 Feb 12  2021 '/path/to/photos/experiment 11/20222601_DSC00057.JPG'

How could I get the script to continue processing other files, because there are still plenty of folders with photos to process?

Version info

$ bash --version
GNU bash, version 5.1.16(1)-release (x86_64-pc-linux-gnu)

$ cat /etc/os-release 
PRETTY_NAME="Ubuntu 22.04.2 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.2 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=jammy

$ uname -mor
5.19.0-32-generic x86_64 GNU/Linux

$ exiftool -ver
12.57
s.k
  • 1,170
  • 2
  • 14
  • 44
  • 1
    If you're using GNU `find`, you can search for non-empty files. You also need parentheses around the `-iname` tests to not match non-regular files for `*.jpeg` and `*.png`: `find "$DIR" -type f \! -empty \( -iname '*.jpg' -o -iname '*.jpeg' -o -iname '*.png' \) ...` – Freddy Mar 02 '23 at 22:49
  • 2
    The reason your script stops is the `set -e` option ... If this is all the code you have in your script, I wonder why you have it set as it adds no apparent benefit ... So, if you just remove that, your script should not stop on empty image files anymore ... @steeldriver Just curious as for why you deleted your answer below ... That is the answer I would actually write :-) – Raffa Mar 03 '23 at 08:28

2 Answers2

2

For the posterity and because I found it very interesting as well, I rebuild steeldriver's answer as a Community wiki:

set -e causes the shell (script) to exit when exiftool returns a non-zero exit status (which it apparently does when passed an empty file).

If you need to run the script with set -e for other reasons, you could either:

  • set +e before the exiftool command and then reset set -e after

or (more idiomatic, I think)

change:

exiftool "${f}" >> output.txt

to:

exiftool "${f}" >> output.txt || true

so that the compound command always exits successfully regardless of the exit status of the simple command exiftool

BTW your loop over the find command's output is fragile - see Why is looping over find's output bad practice?

s.k
  • 1,170
  • 2
  • 14
  • 44
1

Check for an empty file and not ask exiftool to process it:

if [[ -s "${f}" ]] ; then
   exiftool "${f}" >>output.txt
else
    echo "Empty" >>output.txt
fi

Read man bash.

s.k
  • 1,170
  • 2
  • 14
  • 44
waltinator
  • 35,099
  • 19
  • 57
  • 93