Update System E-mail Wrapper Script

This is a bash script I've been using to wrap full system updates (yum -y update) to get the update status e-mailed as a report. I've been using this with Ansible to patch up my virtual environment with the meltdown patches.

The script will perform a full update, and e-mail you the results as you'd have seen in the terminal. It also includes the time taken and current loads after the update.

Usage: ./update-system.sh someone@example.com

The Script

#/bin/bash
#
#  Update helper shell script: wraps full system updates and sends an e-mail
#  when complete. Works with yum, dnf and apt-get.
#
#  Usage:
#    update-system.sh [-hs] [EMAILS]
#
#    -h       : Show this help
#    -s       : Send 'Starting' e-mail
#
#    EMAILS   : A space separated list of e-mail recipients
#
#  Exit codes:
#    0  : Update performed successfully
#    1  : Failed to detect update system (RPM/Aptitude)
#    2  : Could not find yum or dnf on an RPM based system
#    3  : Could not find apt-get on a Debian system
#    4  : Could not find mail command to send mail
#    5  : Updater exited abnormally (none-zero exit code)
#

# Default parameters
send_start_email=0
update_cmd=''

# Update commands, system is auto-detected
apt_update_cmd='apt-get update -y'
dnf_update_cmd='dnf -y update'
yum_update_cmd='yum -y update'

show_usage() {
    echo "Usage:"
    echo "  update-system.sh [-hs] [EMAILS]"
    echo ""
    echo "    -h       : Show this help"
    echo "    -s       : Send 'Starting' e-mail"
    echo ""
    echo "    EMAILS   : A space separated list of e-mail recipients"
    echo ""
    echo "Exit codes:"
    echo "  0  : Update performed successfully"
    echo "  1  : Failed to detect update system (RPM/Aptitude)"
    echo "  2  : Could not find yum or dnf on an RPM based system"
    echo "  3  : Could not find apt-get on a Debian system"
    echo "  4  : Could not find mail command to send mail"
    echo "  5  : Updater exited abnormally (none-zero exit code)"
}

echo "System update helper script. www.cjsavage.com."
# Set which update system to use.
apt_cmd=$(which apt-get)
rpm_cmd=$(which rpm)
if [ -x "${rpm_cmd}" ] ; then
    echo "Running on a RPM based system."
    dnf_cmd=$(which dnf)
    yum_cmd=$(which yum)
    if [ -x "${dnf_cmd}" ] ; then
        update_cmd=$dnf_update_cmd
    elif [ -x "${yum_cmd}" ] ; then
        update_cmd=$yum_update_cmd
    else
        (>&2 echo "Detected RPM based distribution, but did not find dnf or yum.")
        exit 2;
    fi
elif [ -x "$apt_cmd" ] ; then
    echo "Running on an Aptitude based system."
    update_cmd=$apt_update_cmd
else
    (>&2 echo "Could not detect update system (RPM/Aptitude).")
    exit 1;
fi

# Check the mail command is present
mail_cmd=$(which mail)
if [ ! -x "$mail_cmd" ] ; then
    (>&2 echo "Could not find mail command to send mail.")
    exit 4;
fi

email_string=''
# Parse CLI args manually, we need to work everywhere
for ((i=1; i<=$#; i++)); do
    if [ ${!i} = "-s" ]; then
        send_start_email=1
    elif [ ${!i} = "-h" ]; then
        show_usage
        exit 0
    else
        email_string="${email_string},${!i}"
    fi
done;

if [ $send_start_email -eq 1 ]; then
    update_msg="Updates starting on host ${HOSTNAME}."
    echo "Sending start updates e-mail."
    echo $update_msg | mail -s "${update_msg}" $email_string
fi

echo "Updating system..."
update_results=`/usr/bin/time -p $update_cmd 2>&1`
exit_code=$?
if [ $exit_code -eq 0 ]; then
    uptime=`uptime`
    subject="Update successful on ${HOSTNAME}."
    body=$update_results
    echo "Sending successful completion e-mail."
    echo "$body

Uptime: ${uptime}" | mail -s "${subject}" $email_string
    exit 0;
else
    subject="Update failed on ${HOSTNAME}."
    body="Update failed with exit code ${exit_code}.
${update_results}"
    echo "Sending update abnormal exit e-mail."
    echo "$body" | mail -s "${subject}" $email_string
    exit 5
fi