Search code examples
bashwhile-loopffmpegdev-nullbash-trap

How to use trap to terminate while loop containing ffmpeg fed by redirect from /dev/null?


I discovered here Loop calls process that takes a long time to complete. How do I break out of it? that piping from find to a while loop that calls an ffmpeg cli [HandBrakeCLI] will not process more than one input file because ffmpeg has a quirk that it 'eats' all the input list in one go and 'starves' the loop.

The solution was to redirect from /dev/null per http://mywiki.wooledge.org/BashFAQ/089 and that works fine. However, it brings me back to the original problem and the question I set out to solve:

Because /dev/null now has a complete list of all the files feeding HandBrakeCLI, ctrl-c on its own is not enough to quit the loop.

I have tried various permutations of trap, but I can't get it to do anything other than stop HandBrakeCLI processing the current input before it moves on to the next one. Instead of terminating the loop immediately, it also processes the mv right after the HandBrakeCLI line.

So, there are two things I am not getting here: 1. How do I terminate everything with a ctrl-c or kill command? 2. If not dealt with by (1.), how do I prevent the mv inside the loop from being executed?

For the sake of addressing the question, this is the simplified version of the code:

#!/bin/bash

source_dir="/Volumes/Volumename"
dest_dir="/Volumes/Volumename/Converted/"
finished_dir="Volumes/Volumename/Processed/"


find "$source_dir" -type d -name "VIDEO_TS" | while read -r dir; do
  name=${dir%/VIDEO_TS}
  mov_dir=${dir%/*}
  name=${name##*/}
  ./HandBrakeCLI -i "$dir" -o "$dest_dir/$name.m4v" </dev/null
  mv "$mov_dir" "finished_dir"
done

Solution

  • Try to to append || break:

    ./HandBrakeCLI -i "$dir" -o "$dest_dir/$name.m4v" </dev/null || break