Bash Script 3: Error Checking

The last few posts, I’ve been talking about bash scripts. Today, I’m going to talk about error checking/handling. So far, the script has been fairly simple, but it does make some assumptions, such as having avconv installed, the video file being valid, and the output file not existing. Well, for that last one, the output file would be overwritten if it does exist, so we’d loose data and that’s always a bad thing. Without further ado, let’s get started.

Checking for an installed program

This is super simple. Just call the ‘which’ command. In our script, we make sure of avconv, so the test is this:

which avconv
if [ $? -ne 0 ]
then
  echo 'avconv not found'
  echo 'This script requires avconv.'
  echo 'Please install it and try again'
  exit 99
fi

Here, I’m calling which and checking the exit code, stored in $?. If it’s not equal to 0, the program was not found and the script informs the user and exits.

Checking for an existing output file

For this, it’s the same test covered in the last post, -f. To make things easier, let’s assign the output filename to a variable and then check it.

OUTPUT_FILE="$1.mkv"
if [ -f "$OUTPUT_FILE" ]
then
  echo 'Warning: The output file already exists: $OUTPUT_FILE'
  echo 'Please rename that file'
  exit 98
fi

Checking for a valid video file

This one is a bit tricky. Instead of verifying that the file is correct, let’s just check for the output of avconv, which will return a 0 if successful.

avconv -i "$1" $VERBOSITY_OPTION -c:v libx264 \
  -preset medium -crf 20 -c:a mp3 "$OUTPUT_FILE";
if [ $? -ne 0 ]
then
  echo 'There was a problem converting the video.'
  echo 'Your file may be corrupt.'
  echo 'Please verify the video file.'
  exit 97;
fi

Putting it all together

Here’s the full updated script:

#!/bin/bash

###############################
#                             #
# convert-video.sh            #
#                             #
# Written By: Barry Gilbert   #
# Written On: Oct 2018        #
#                             #
###############################

# Shows the end user the usage message
showUsage() {
  echo "" >&2
  echo "Usage: convert-video.sh [-h] [-v] [video-filename]" >&2
  echo "  -h  shows this help information" >&2
  echo "  -v  verbosity for avconv." >&2
  echo "      Multiple -v options increase the verbosity." >&2
  echo "      The maximum is 2." >&2
  echo "  video-filename video file to convert" >&2
  exit 99;
}

VERBOSITY_LEVEL=0

# Loop through the options passed in by the user
while getopts ":h" opt; do
  case $opt in
    h)
      showUsage
      ;;
    v)
      VERBOSITY_LEVEL=$((VERBOSITY_LEVEL+1))
      ;;
    \?)
      # Bad option, YELL AT USER
      echo 'Invalid option: -$OPTARG"
      showUsage
      ;;
  esac
done

# Reset the parameter, so we can grab the filename
shift $((OPTIND-1))

VERBOSITY_OPTION=""
if [ VERBOSITY_LEVEL -eq 1 ]
then
  VERBOSITY_OPTION=" -loglevel=verbose"
elif [ VERBOSITY_LEVEL -eq 2 ]
then
  VERBOSITY_OPTION=" -loglevel=debug"
fi

# Check to see if a filename was provided
# $# will contain the number of arguments
# If the number of arguments is not 1
if [ $# -ne 1 ]
then
  echo 'No File Provided';
  showUsage;
fi

# $1 will contain the first argument
# Check to see if $1 is not a file
if [ ! -f "$1" ]
then
  echo 'File Not Found';
  showUsage;
fi

# Check to see if avconv is installed
which avconv
if [ $? -ne 0 ]
then
  echo 'avconv not found'
  echo 'This script requires avconv.'
  echo 'Please install it and try again'
  exit 99
fi

# Check to make sure output file doesn't exist
OUTPUT_FILE="$1.mkv"
if [ -f "$OUTPUT_FILE" ]
then
  echo 'Warning: The output file already exists: $OUTPUT_FILE'
  echo 'Please rename that file'
  exit 98
fi

# Convert the video
avconv -i "$1" $VERBOSITY_OPTION -c:v libx264 \
  -preset medium -crf 20 -c:a mp3 "$OUTPUT_FILE";
if [ $? -ne 0 ]
then
  echo 'There was a problem converting the video.'
  echo 'Your file may be corrupt.'
  echo 'Please verify the video file.'
  exit 97;
fi