Ubuntu/Linux Mint Update Script

wget http://www.haganfox.net/site/uploads/Main.UbuntuUpdateScript/update.sh.txt

This script upgrades your Debian, Ubuntu or Linux Mint system's packages, then reports whether or not a reboot is required.

Purpose

Up-to-date with a single command

Graphical system-update tools will notify you when a reboot is required. This script was created to do that from the CLI. Beyond just that, it improves automation so you can conveniently update your system with minimum fuss.

The script automatically adapts to your system's capabilities and chooses the best upgrade option available. Installed packages are reported so you can stay informed and react accordingly (restart your browser if it has been updated, for example).

A -y parameter (assume "yes") allows you to upgrade without prompting, making the process even more convenient because you can update with a single command:

 user@host ~ $ ./update.sh -y

The script is compatible with any currently-supported release of Ubuntu or Linux Mint.

The Script

Text version: update.sh.txt

Right-click to download, or use:
wget http://www.haganfox.net/site/uploads/Main.UbuntuUpdateScript/update.sh.txt
MD5SUM: 29fe72b360ee7cb8ae8e620cbfe145ab
SHASUM: cb8188a88762c5507f9bc9910377bec8f7c30bab
SHA256SUM: be7291b92584f6ca15e50fa316c8207db92482ec8b61cbf93a73e635094d6eb9

#!/bin/bash
## This script updates your system's packages, then reports
## whether or not a reboot is required.
##
## A "-y" parameter assumes "yes" and upgrades without
## prompting. (Useful when upgrading multiple systems.)
## 
## http://www.HaganFox.net/Main/UbuntuUpdateScript

##  SETTING
##
##  Prevents a sync if the local package index is up-to-date
##  The index is "up-to-date" for this many minutes (0 = always sync)
recent_sync=10

##  Get this script's basename
script_name=${0##*/}

##  Check for the "assume-yes" parameter
if [ "$1" = "-y" ]; then assumeyes="-y"; fi

##  Check for the prerequisite package
##  If it's not installed, offer to install it
prereq="update-notifier-common"
if [ $(dpkg-query -W -f='${Status}' $prereq 2>/dev/null \
 | grep -c "ok installed") -eq 0 ]
then
  echo
  echo "The \"$prereq\" package is not installed. It's"
  echo "required to determine whether a reboot will be required."
  echo
  read -p "Install $prereq now? [Y/n]? " choice
  case "$choice" in 
    y|Y|yes|''  ) sudo apt-get install $prereq;;
  esac
fi

##  Determine if the package database needs to be synchronized
sync_age=$(expr $(date -d now +%y%m%d%H%M)\
 - $(date -r /var/lib/apt/periodic/update-success-stamp +%y%m%d%H%M))
if [ $sync_age -lt $recent_sync ]; then
  sync_current="Package database was synchronized $sync_age minutes ago."
fi

##  Sync the local package database and upgrade
loglinesb4=$(wc -l </var/log/dpkg.log) # Count logs lines b4 upgrading
if command -v apt >/dev/null ; then # System has APT 1.0 or greater
  if [ "$sync_current" ]; then echo $sync_current
  else sudo apt update
  fi
  sudo apt-get $assumeyes --with-new-packages upgrade
  if [ $? -ne 0 ]; then 
    # --with-new-packages is not understood by apt-get
    echo "$script_name: Switching to \"apt upgrade\""
    sudo apt $assumeyes upgrade
  fi
  if [ $? -ne 0 ]; then
    # -y is not understood by apt
    aptget_fallback=1
    echo "$script_name: Switching to \"apt-get dist-upgrade\""
    sudo apt-get $assumeyes dist-upgrade
  fi
else # Ubuntu 12.04
  if [ "$sync_current" ]; then echo $sync_current
  else sudo apt-get update
  fi
  sudo apt-get $assumeyes dist-upgrade
fi

##  Report the packages that were installed
loglinesafter=$(wc -l </var/log/dpkg.log) # how many lines now?
newloglines=$((loglinesafter-loglinesb4)) # how many new lines?
if [ $newloglines -ne 0 ]; then
  echo
  echo "$script_name: Installed-packages list (from logfile):"
  tail -$newloglines /var/log/dpkg.log \
   | grep 'status installed' \
   | awk '{$1=$2=$3=""; print substr($0,4)}'
fi

##  If a -y parameter caused fallback to "apt-get dist-upgrade"
if [ "$aptget_fallback" ]; then
  echo
  echo "$script_name notice:" 
  echo "\"apt-get dist-upgrade\" was used because the -y parameter"
  echo "cannot be used together with \"apt upgrade\" on this system."
fi

##  Exit if the update-notifier-common package is missing
if [ $(dpkg-query -W -f='${Status}' $prereq 2>/dev/null \
 | grep -c "ok installed") -eq 0 ];
then
  echo 
  echo "$script_name: Unable to determine whether a reboot is required"
  echo "$script_name: because \"$prereq\" is not installed."
  echo
  exit
fi

##  Report the reboot-required status
if [ -f /var/run/reboot-required ]; then
  echo
  echo "$script_name: Done."
  cat /var/run/reboot-required
  echo
  echo "Packages that requested reboot:"
  cat /var/run/reboot-required.pkgs
  echo
else
  echo
  echo "$script_name: Done."
  echo "No restart is required."
  echo
fi

Requirement

Reporting whether a reboot is required requires the update-notifier-common package. The script offers to install that package if it's not installed.

Installation

Download the script using your browser or use wget to retrieve it.

Move the script, rename it, set it to executable.

 user@host ~/foo $ cd
 user@host ~ $ mv Download/update.sh.txt .
 user@host ~ $ mv update.sh.txt update.sh
 user@host ~ $ chmod 700 update.sh

Run the script with

 user@host ~ $ /update.sh

or

 user@host ~ $ ./update.sh -y

The -y parameter assumes "yes" and upgrades without prompting.

For what it's worth, I almost always use the -y parameter and have experienced 100% success doing so. Your mileage may vary if you compile your own software or you have made unusual customizations to your package system.

Answers

Why check for the apt command rather than just using apt-get?

Because apt upgrade can add new packages to resolve package conflicts. Packages are never removed, only upgraded or (sometimes) added.

You can (and should) occasionally run apt full-upgrade to check for packages that may be removed in order to resolve package conflicts.

For apt-get, why use dist-upgrade rather than upgrade?

dist-upgrade intelligently handles changing dependencies that are introduced with new versions of packages. New packages may be added or removed in order to resolve package conflicts. This is nearly always safe except in rare cases, for example if you compile your own software or you have made unusual customizations to your package system.

See also:

Changelog

2016-10-24

  • Added a setting to avoid wasting time/bandwidth synchronizing the package database if it's already synchronized. It was added because the script is often run shortly after booting the system, and there's little need to sync the local package database if it has just been sync'd as part of the boot/login process.
Page last modified on June 15, 2017
Powered by PmWiki