Automatic check for package updates in Raspbian

Since a few days I have a Raspberry Pi continuously running and at the moment measuring the room temperature. Since I do not log in regularly to the system to check for operating system (Raspbian) updates, I wanted to get notified by mail when there are updates available.

There is a program which can do this, which is called apticron. But there is a ploblem if you want to run it on the Raspberry. It needs a mail server installed. And because the raspberry has not much RAM, I did not want to install the mail server. So in my article about sending mail from the raspberry I describe how to send mail without running a mail server.

To check for available updates I wrote a script which can be called by the cron regularly, e.g. once per night. If there are updates available it sends a mail by calling the command line mail client mailx.

You can use the script by putting it into your home directory on the raspberry and adding a line to a config file for cron like /etc/cron.d/apt-checkupdates:

0 3 * * * root /home/pi/ --quiet --mailto

This runs the script under the root account each night at 3am. It updates the package lists with apt-get update and then calls apt-get -s dist-upgrade to simulate the installation of available updates. It then parses the output of apt-get and sends a mail with the results.

For testing you can also call the script in the console. To get help for the available command line parameters, call it like this:

./ --help

And here's the script:

# $Id: 17 2012-12-27 13:24:50Z andreas $
# This script checks for available upgrades on debian-bases systems and prints
# a message and / or sends a mail. It is intended to be run by cron.
# Example cron file under /etc/cron.d/apt-updatecheck
# 0 3 * * * root /opt/scripts/apt-updatecheck --quiet --mailto <email-address>
# Based on the work of these people:
# Author:
# Modified by:

# Default: Show messages on console

# check parameters
while [ $# -gt 0 ]
  case "$1" in
    # get next param
    # check at least if it contains @
    if [ `echo $1 | awk '/@/'` ]
      echo "--mailto expects an e-mail"
      exit 1
    echo "usage: $0 [--quiet] [--mailto]"
    echo "--quiet [quiet mode, no output to console]"
    echo "--mailto [send output via email]"
    exit 0

# update package lists
apt-get update 2>&1 > /dev/null

# calculate upgrades and capture output
OUTPUT=`apt-get -s ${UPGRADE_MODE} 2>&1`

# calculate number of upgradeable packages
UPDATES=`echo "$OUTPUT" | grep -E '^Inst ' | wc -l`
if [ $UPDATES -ne 0 ]
  # get list of packages
  PACKAGES=`echo "$OUTPUT" | grep -E '^Inst' | cut -d ' ' -f 2`

  # assemble text for message / mail.
  MSG="These ${UPDATES} packages need an update on host '`hostname`':\n"
  MSG="${MSG}Please perform ‘apt update && apt upgrade’ as root."

  # if MAIL_TO variable is not empty, send a mail.
  if [ -n "$MAIL_TO" ]
    echo -e $MSG | mailx -s "[`hostname`] $UPDATES update(s) available" $MAIL_TO

  # if quiet flag is not set, print out message.
  if [ $QUIET -eq 0 ]
    echo -e $MSG

exit 0
LinkedIn logo mail logo