-
Notifications
You must be signed in to change notification settings - Fork 0
/
rmkernels
executable file
·93 lines (85 loc) · 3.51 KB
/
rmkernels
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#!/usr/bin/env bash
set +xv
## rmkernels - uninstall extraneous kernels on Ubuntu based systems
## Usage: bash rmkernels [-h|--help] [-f|--force] [<version>]...
## -h, --help: display help text
## -f, --force: force removal of newer than currently running kernel
## anything installed that matches <version> will be proposed for removal
## Required: grep, sed, find, coreutils(sort, uname, tail), dpkg, apt. sudo
## If bootctlu is present and active, it will be called to cull the entries
Usage(){
cat <<-EOS
rmkernels - uninstall extraneous kernels on Ubuntu based systems
Usage: bash rmkernels [-h|--help] [-f|--force] [<version>]...
-h, --help: display help text
-f, --force: force removal of newer than currently running kernel
<version>: pattern for proposed removal of installed packages
EOS
}
Main(){
## Process commandline
local force=0 pat= pkgsf= pkgpat=
while [[ $1 ]]
do
[[ $1 = -h || $1 = --help ]] && Usage && return 0
[[ $1 = -f || $1 = --force ]] && force=1 || pat+=" $1" ## Extra removals
shift
done
## Find superfluous kernels
all=$(find /boot/vmlinuz-* | ## Kernel images in /boot
sed 's@^/boot/vmlinuz-@@' | ## Truncate to the version
grep -v '\.efi\.signed' | ## Exclude additional efi-signed versions
sort -Vr) ## Sort by version
cur=$(uname -r) ## Currently running kernel version
non=$(grep -v "$cur" <<<"$all") ## Non-running kernels in /boot
echo -e "Found kernel images in /boot:\n$cur (currently running)\n$non"
## Superfluous versions: latest of same major.minor version all kernels
sf=$(ao= bo=
while IFS='.' read a b c
do
[[ $a || $b || $c ]] && [[ $ao = $a && $bo = $b ]] && echo "$a.$b.${c%-*}"
ao=$a bo=$b
done <<<"$all"
)
grep -q "${cur%-*}" <<<"$sf" && ## Currently running kernel is superfluous!
echo -e "\nThe currently running kernel is superfluous itself!" &&
echo "It can only be removed after a reboot with a newer kernel" &&
sf=$(grep -v "${cur%-*}" <<<"$sf")
nall=$(wc -l <<<"$all")
nsf=$(wc -l <<<"$sf")
((nall-nsf<2 && nsf>0)) && ## Keep at least 1 fallback kernel
sf=$(tail -n +2 <<<"$sf") ## Remove most recent from superfluous list
## Check kernel images and commandline patterns against installed packages
sedpkg='s@^[^ ]*[ ]*\([^ ]*\).*@\1@' ## Installed packages sed pattern
ipkg=$(dpkg -l | tail -n +6 |sed "$sedpkg") ## Installed packages
sedsf=$(sed 's@^@ -e @g' <<<' '$sf) ## Sed pattern for superfluous kernels
[[ $sf ]] && pkgsf=$(grep $sedsf <<<"$ipkg") ## Superfluous packages
if [[ $pkgsf ]]
then ## Superflous kernels installed as packages
echo -e "\nRemoving:\n$sf\n\nFound packages:\n$pkgsf"
else
echo "No superfluous packages found based on kernel images in /boot"
fi
## Check the commandline patterns
if [[ $pat ]]
then
pkgpat=$(echo "$ipkg" |grep ${pat// / -e })
pkgpat=$(grep -v "$cur" <<<"$pkgpat") ## Not current kernel
if [[ $pkgpat ]]
then
echo -e "\nExtra removal patterns from commandline:$pat\nPackages:" $pkgpat
else
echo -e "\nNo packages found based on removal patterns on commandline:$pat"
fi
fi
## Removing incompletely uninstalled packages
rc=$(dpkg -l |grep ^rc |sed "$sedpkg")
ic=$(dpkg -l |grep ^ic |sed "$sedpkg")
[[ $rc || $ic ]] &&
echo -e "\nUninstalled but not properly removed packages:\n" $rc $ic "\n"
## Purge all superfluous and extra versions, and improperly removed packages
[[ $pkgsf || $pkgpat || $rc ]] && sudo apt purge $pkgsf $pkgpat $rc ||
echo "Nothing to remove"
[[ $ic ]] && sudo dpkg -P $ic || echo "Nothing to wipe"
}
Main $*