Check Your OS and When it was Last Upgraded - Bash Shell Script

I like writing small utility scripts for Linux. This one IDs the operating system, and tells you how long it's been since you last updated the packages on the system (works for Debian, Raspbian, Fedora - probably other variants of Debian and Fedora with minor tweaks). There's a catch: this is tied to how I do my upgrades, at least on Debian. It searches specifically for dist-upgrade - if you upgrade by some other method, you may need to tweak this. Some explanation follows.

#!/usr/bin/env bash
#
#   Filename:      chkos
#   Purpose:       Check the OS for version and updates.
#

deblastupdate() {
    # Grab all the apt history - in the correct order - and look for the
    # last dist-upgrade event.

    # shellcheck disable=SC2045  # "Iterating over ls output is fragile. Use
    # globs."  Globs won't work here.
    for file in $(ls -1tr /var/log/apt/history.log*)
    do
        if [[ ${file} =~ .gz$ ]]
        then
            zcat "${file}"
        else
            cat "${file}"
        fi
    done | grep -B1 "dist-upgrade" | grep "Start-Date" | tail -n 1 | awk '{ print $2,$3 }'
}

fedlastupdate() {
    dnf history --reverse | grep update | awk -F '|' '{ print $3 }' | tail -n 1
}

if command -v lsb_release > /dev/null 2> /dev/null
then
    # Show us the OS description:
    lsb_release -d
else
    echo "STOPPING: the 'lsb_release' binary isn't installed."
    echo "For Fedora, install the 'redhat-lsb-core' package,"
    echo "for Debian, install the 'lsb_release' package."
    exit 1
fi

osid="$(lsb_release -i | awk '{ print $NF }')"
echo -n "Last updated: "
case "${osid}" in
    "Debian"|"Raspbian")
        lastup="$(deblastupdate)"
        ;;
    "Fedora")
        lastup="$(fedlastupdate)"
        ;;
    *)
        echo "OS '${osid}' is unknown to this script, please update the script."
        ;;
esac
echo -n "${lastup} ("
echo -n $(( ( $(date "+%s") - $(date --date="${lastup}" "+%s") ) / (60*60*24) ))
echo " days ago)"

This requires the lsb_release command, which isn't a default install. But it's very small and a standard package for most OSes.

For Fedora, getting a history of updates is as easy as dnf history --reverse. For Debian/Raspbian it's trickier: you have to list the contents of the /var/log/apt/history.log* files, and you have to list them in sequential order, then do some text parsing. Finally, we convert both the current date and the date of the last update to "seconds since the Epoch" (%s), get the difference, and convert it back to days instead of seconds.

On most systems, the output looks something like this:

$ chkos
Description:    Debian GNU/Linux 11 (bullseye)
Last updated: 2022-12-11 12:20:07 (0 days ago)

or:

$ chkos
Description:    Fedora release 36 (Thirty Six)
Last updated:  2022-12-09 09:27  (2 days ago)

One use I'm considering is to add a command line option to only output the number of days since the last update. That could be useful for scripting: if the output exceeds some value like "14," automatically run upgrades. Or something: still thinking about it.

Postscript

What does it say about my life that I can recall approximately one third of the strftime date date formats (%s, but also the difference between %d and %D)?