Last active
May 6, 2019 06:32
-
-
Save jeenuv/4f62cf2cc0f29f50fcaa377983ebdf2d to your computer and use it in GitHub Desktop.
Find and list older kernel packages to stdout
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/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