Skip to content

Instantly share code, notes, and snippets.

@jeenuv
Last active May 6, 2019 06:32
Show Gist options
  • Select an option

  • Save jeenuv/4f62cf2cc0f29f50fcaa377983ebdf2d to your computer and use it in GitHub Desktop.

Select an option

Save jeenuv/4f62cf2cc0f29f50fcaa377983ebdf2d to your computer and use it in GitHub Desktop.
Find and list older kernel packages to stdout
#!/usr/bin/env python3
#
# Script to print out outdated Linux kernel packages, and print them to stdout.
# Can be used as:
#
# sudo -v
# python3 cleanup_linux_pkg.py | xargs sudo apt-get remove -y
#
# But please do confirm the output packages are correct by inspecting the
# printed list first!
import itertools
import subprocess
import sys
class VersionError(Exception):
pass
# Digests a package name into numerics, and allows for 'lower' comparison in
# order to detect older versions. For example, linux-headers-4.13.0-37-generic
# is digested into [4, 13, 0, 37].
#
# Raises VersionError upon if not happy.
class Version:
def __init__(self, ver_string):
self.ver_list = []
# Split at hyphens first
for item in ver_string.split("-"):
# Split each item at ".", expecting numbers.
numbers = item.split(".")
for n in numbers:
try:
val = int(n)
except ValueError:
break
else:
self.ver_list.append(val)
if not self.ver_list:
# No numerics found in the string
raise VersionError("Cannot digest " + ver_string)
def __lt__(self, other):
# Less than comparison
if not isinstance(other, Version):
other = Version(other)
# Extend the shorter list with zeroes
final = itertools.zip_longest(self.ver_list, other.ver_list,
fillvalue=0)
for first, second in final:
# Everything except the last one may be equal. For example, 4.3.1
# and 4.3.2
if first > second:
return False
# Last item must not be equal
if first == second:
return False
return True
def __str__(self):
return str(self.ver_list)
def __repr__(self):
return "<Version {}>".format(str(self))
def stdout_of(cmd):
with subprocess.Popen(cmd.split(), stdout=subprocess.PIPE,
universal_newlines=True) as proc:
for line in proc.stdout:
yield line
# Get kernel release version
kernel_release = next(stdout_of("uname -r"))
current_version = Version(kernel_release)
for line in stdout_of("dpkg -l"):
fields = line.split()
if len(fields) < 2:
continue
# Check for an installed Linux package
installed, package = fields[0:2]
if installed != "ii" or not package.startswith("linux-"):
continue
try:
pkg_version = Version(package)
except VersionError:
print("Warning: no version found in package " + package,
file=sys.stderr)
continue
if pkg_version < current_version:
print(package)
# vim:set tw=80:
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment