So löschen Sie selektiv alte Kernel auf einmal

7

Die hoch bewerteten Fragen und Antworten Wie entferne ich alte Kernelversionen, um das Startmenü zu bereinigen? bietet keine einfache Möglichkeit, ältere Kernel selektiv zu löschen, es sei denn, zusätzliche Anwendungen sind installiert, z. B. Ubuntu-Tweak .

Der Bash-Einzeiler zum Löschen nur alter Kernel- Fragen und Antworten bietet eine Lösung zum Löschen aller alten Kernel, aber ich möchte den letzten Kernel in jeder Generation behalten. dh entfernen Sie 4.7.1, 4.7.2 ... aber behalten Sie 4.7.5.

Gibt es eine Möglichkeit, durch eine Liste aller installierten Kernel zu scrollen und bestimmte zum Löschen auszuwählen? Das Löschen des aktuell ausgeführten Kernels sollte nicht zulässig sein.

WinEunuuchs2Unix
quelle
Es gibt eine Person, die schon seit geraumer Zeit an einem solchen Skript arbeitet. Es gibt einen Launchpad-Fehlerbericht / eine Anfrage dazu. Das Problem ist, dass er Geld will, und er hat mich noch nie testen lassen.
Doug Smythies
Entschuldigung, es gibt zwei Fehlerberichte, und ich habe Sie auf den falschen hingewiesen. Sehen Sie diesen .
Doug Smythies

Antworten:

5

Der Vorteil dieser Antwort ist, dass natives Ubuntu Bash ohne Installation von Anwendungen von Drittanbietern verwendet wird. Benutzer von benutzerdefinierten Kerneln, die nicht verwendet habenaptdpkg dieses Bash-Skript oder ändern können, um es ihren Anforderungen anzupassen.

Zenity-basierte Lösung

Zenity bietet eine GUI-Schnittstelle zum Terminal. Hier wird eine Liste von Kerneln verarbeitet und einzelne ausgewählt:

rm-kernels 1.png

Der Dialogtitel gibt die Anzahl der Kernel, ihre Gesamtgröße und die aktuell gestartete Kernelversion an. Der aktuelle Kernel wird von den Gesamtsummen des Titels ausgeschlossen und nicht in der Kernelliste angezeigt.

Das Änderungsdatum ist normalerweise das Datum, an dem der Kernel veröffentlicht wurde. Auf meinem System wird dieses Datum jedes Mal "berührt", wenn der Kernel mit einem Cron- Neustart-Skript gestartet wird ( Wie erfahren Sie, wann eine bestimmte Kernel-Version zuletzt gestartet wurde? ).

Für jeden Kernel wird seine Größe innerhalb des /bootVerzeichnisses angegeben. Dann wird die Gesamtgröße des Kernels für die drei Verzeichnisse summiert. / boot, / usr / src / kernel_version und / lib / modules / kernel_version .

Wenn kein Parameter an rm-kernelsdie Gesamtgröße übergeben wird, wird diese geschätzt und der Titel zeigt "Est. Total". Dies spart Zeit beim Ausführen des duBefehls. Dies kann 30 Sekunden bis 90 Minuten dauern, je nachdem, wie viele Kernel Sie haben und ob Sie eine SSD oder eine Festplatte haben. Wenn Sie einen Parameter übergeben, duwird er verwendet, um die Kernelgrößen zu erhalten, und der Titel zeigt "Real Total", wie der obige Beispielbildschirm zeigt.

apt-get purge gibt Ihnen die Möglichkeit abzubrechen

Sie können alles anzeigen, was gelöscht wird, apt purgeund haben die Möglichkeit, fortzufahren oder abzubrechen:

The following packages will be REMOVED:
  linux-headers-4.4.0-78* linux-headers-4.4.0-78-generic*
  linux-headers-4.4.8-040408* linux-headers-4.4.8-040408-generic*
  linux-headers-4.6.3-040603* linux-headers-4.6.3-040603-generic*
  linux-headers-4.8.12-040812* linux-headers-4.8.12-040812-generic*
  linux-headers-4.9.0-040900* linux-headers-4.9.0-040900-generic*
  linux-headers-4.9.9-040909* linux-headers-4.9.9-040909-generic*
  linux-image-4.4.0-78-generic* linux-image-4.4.8-040408-generic*
  linux-image-4.6.3-040603-generic* linux-image-4.8.12-040812-generic*
  linux-image-4.9.0-040900-generic* linux-image-4.9.9-040909-generic*
  linux-image-extra-4.4.0-78-generic*
0 upgraded, 0 newly installed, 19 to remove and 1 not upgraded.
After this operation, 1,794 MB disk space will be freed.
Do you want to continue? [Y/n] 

apt purgeBerichte 1.784 MB werden freigegeben, aber die tatsächliche Summe 2.379 MB. Ich weiß nicht, warum es anders ist.

Anstatt die Kernel einzeln zu löschen und update-grubwiederholt in einer zeitaufwändigen Schleife aufgerufen zu werden, werden die Auswahlen auf einmal gelöscht.

Der Code

Kopieren Sie diesen Code in eine Datei mit dem Namen rm-kernelsin /usr/local/bin:

#!/bin/bash

# NAME: rm-kernels
# PATH: /usr/local/bin
# DESC: Provide zenity item list of kernels to remove

# DATE: Mar 10, 2017. Modified Aug 5, 2017.

# NOTE: Will not delete current kernel.

#       With 10 kernels on an SSD, empty cache from sudo prompt (#) using:
#       # free && sync && echo 3 > /proc/sys/vm/drop_caches && free
#       First time for `du` 34 seconds.
#       Second time for `du` 1 second.
#       With a magnetic hard disk, and empty memory cache:
#       the first `du` command averages about 20 seconds per kernel.
#       the second `du` command averages about 2.5 seconds per kernel.

# PARM: If any parm 1 passed use REAL kernel size, else use estimated size.
#       By default `du` is not used and estimated size is displayed.

# Must be running as sudo
if [[ $(id -u) != 0 ]]; then
    zenity --error --text "root access required. Use: sudo rm-kernels"
    exit 99
fi

OLDIFS="$IFS"
IFS="|"
choices=()

current_version=$(uname -r)

for f in /boot/vmlinuz*
do
    if [[ $f == *"$current_version"* ]]; then continue; fi # skip current version
    [[ $f =~ vmlinuz-(.*) ]]
    v=${BASH_REMATCH[1]}        # example: 4.9.21-040921-generic
    v_main="${v%-*}"            # example: 4.9.21-040921

    n=$(( n + 1 ))              # increment number of kernels

    # Kernel size in /boot/*4.9.21-040921-generic*
    s=$(du -ch /boot/*-$v* | awk '/total/{print $1}')

    if [[ $# -ne 0 ]] ; then    # Was a parameter passed?
        if [[ -d "/usr/src/linux-headers-"$v_main ]] ; then
             # Kernel headers size in /usr/src/*4.9.21-040921*
             s2=$(du -ch --max-depth=1 /usr/src/*-$v_main* | awk '/total/{print $1}')
        else
             s2="0M"            # Linux Headers are not installed
        fi
        # Kernel image size in /lib/modules/4.9.21-040921-generic*
        s3=$(du -ch --max-depth=1 /lib/modules/$v* | awk '/total/{print $1}')
    else
        # Estimate sizof of optional headers at 125MB and size of image at 220MB
        if [[ -d "/usr/src/linux-headers-"$v_main ]] ; then
             s2="125M"
        else
             s2="0M"            # Linux Headers are not installed
        fi
        s3="220M"
    fi

    # Strip out "M" provided by human readable option of du and add 3 sizes together
    c=$(( ${s//[^0-9]*} + ${s2//[^0-9]*} + ${s3//[^0-9]*} ))
    s=$(( ${s//[^0-9]*} )) # Strip out M to make " MB" below which looks nicer
    t=$(( t + c ))
    s=$s" MB"
    c=$c" MB"
    d=$(date --date $(stat -c %y $f) '+%b %d %Y') # Last modified date for display
    choices=("${choices[@]}" false "$v" "$d" "$s" "$c")
done

# Write Kernel version and array index to unsorted file
> ~/.rm-kernels-plain # Empty any existing file.
for (( i=1; i<${#choices[@]}; i=i+5 )) ; do
    echo "${choices[i]}|$i" >> ~/.rm-kernels-plain
done

# Sort kernels by version number
sort -V -k1 -t'|' ~/.rm-kernels-plain -o ~/.rm-kernels-sorted

# Strip out keys leaving Sorted Index Numbers
cut -f2 -d '|' ~/.rm-kernels-sorted > ~/.rm-kernels-ndx

# Create sorted array
SortedArr=()
while read -r ndx; do 
    end=$(( ndx + 4 ))
    for (( i=$(( ndx - 1 )); i<end; i++ )); do
        SortedArr+=("${choices[i]}")
    done
done < ~/.rm-kernels-ndx

rm ~/.rm-kernels-plain ~/.rm-kernels-sorted ~/.rm-kernels-ndx

if [[ $# -ne 0 ]] ; then    # Was a parameter passed?
    VariableHeading="Real Total"
else
    VariableHeading="Est. Total"
fi

# adjust width & height below for your screen 640x480 default for 1920x1080 HD screen
# also adjust font="14" below if blue text is too small or too large

choices=(`zenity \
        --title "rm-kernels - $n Kernels, Total: $t MB excluding: $current_version" \
        --list \
        --separator="$IFS" \
        --checklist --multiple \
        --text '<span foreground="blue" font="14">Check box next to kernel(s) to remove</span>' \
        --width=800 \
        --height=480 \
        --column "Select" \
        --column "Kernel Version Number" \
        --column "Modified Date" \
        --column "/boot Size" \
        --column "$VariableHeading" \
        "${SortedArr[@]}"`)
IFS="$OLDIFS"

i=0
list=""
for choice in "${choices[@]}" ; do
    if [ "$i" -gt 0 ]; then list="$list- "; fi # append "-" from last loop
    ((i++))

    short_choice=$(echo $choice | cut -f1-2 -d"-")
    header_count=$(find /usr/src/linux-headers-$short_choice* -maxdepth 0 -type d | wc -l)

    # If -lowlatency and -generic are purged at same time the _all header directory
    # remains on disk for specific version with no -generic or -lowlatency below.
    if [[ $header_count -lt 3 ]]; then
        # Remove all w.x.y-zzz headers
        list="$list""linux-image-$choice- linux-headers-$short_choice"
    else
        # Remove w.x.y-zzz-flavour header only, ie -generic or -lowlatency
        list="$list""linux-image-$choice- linux-headers-$choice" 
    fi

done

if [ "$i" -gt 0 ] ; then
     apt-get purge $list
fi

HINWEIS: Sie müssen sudoKräfte verwenden, um die Datei mit Ihrem bevorzugten Editor zu speichern.

So machen Sie die Datei ausführbar:

sudo chmod +x /usr/local/bin/rm-kernels

Serverversion

rm-kernels-serverist die Serverversion zum selektiven Löschen von Kerneln auf einmal. Anstelle eines grafischen GUI-Dialogfelds wird ein textbasiertes Dialogfeld verwendet, um die zu bereinigenden Kernel auszuwählen.

  • Bevor Sie das Skript ausführen, müssen Sie die Dialogfunktion installieren mit:

    sudo apt install dialog

Dialog ist in der Standardinstallation von Ubuntu Desktop, jedoch nicht in Ubuntu Server.

Beispielbildschirm

rm-kernels-server 1

rm-kernels-server Bash-Code

#!/bin/bash

# NAME: rm-kernels-server
# PATH: /usr/local/bin
# DESC: Provide dialog checklist of kernels to remove
#       Non-GUI, text based interface for server distro's.

# DATE: Mar 10, 2017. Modified Aug 5, 2017.

# NOTE: Will not delete current kernel.

#       With 10 kernels on an SSD, empty cache from sudo prompt (#) using:
#       # free && sync && echo 3 > /proc/sys/vm/drop_caches && free
#       First time for `du` 34 seconds.
#       Second time for `du` 1 second.
#       With a magnetic hard disk, and empty memory cache:
#       the first `du` command averages about 20 seconds per kernel.
#       the second `du` command averages about 2.5 seconds per kernel.

# PARM: If any parm 1 passed use REAL kernel size, else use estimated size.
#       By default `du` is not used and estimated size is displayed.

# Must be running as sudo
if [[ $(id -u) != 0 ]]; then
    echo "root access required. Use: sudo rm-kernels-server"
    exit 99
fi

# Must have the dialog package. On Servers, not installed by default
command -v dialog >/dev/null 2>&1 || { echo >&2 "dialog package required but it is not installed.  Aborting."; exit 99; }

OLDIFS="$IFS"
IFS="|"
item_list=() # Deviate from rm-kernels here.

current_version=$(uname -r)
i=0
for f in /boot/vmlinuz*
do
    if [[ $f == *"$current_version"* ]]; then continue; fi # skip current version
    [[ $f =~ vmlinuz-(.*) ]]
    ((i++)) # Item List
    v=${BASH_REMATCH[1]}        # example: 4.9.21-040921-generic
    v_main="${v%-*}"            # example: 4.9.21-040921

    n=$(( n + 1 ))              # increment number of kernels

    # Kernel size in /boot/*4.9.21-040921-generic*
    s=$(du -ch /boot/*-$v* | awk '/total/{print $1}')

    if [[ $# -ne 0 ]] ; then    # Was a parameter passed?
        if [[ -d "/usr/src/linux-headers-"$v_main ]] ; then
             # Kernel headers size in /usr/src/*4.9.21-040921*
             s2=$(du -ch --max-depth=1 /usr/src/*-$v_main* | awk '/total/{print $1}')
        else
             s2="0M"            # Linux Headers are not installed
        fi
        # Kernel image size in /lib/modules/4.9.21-040921-generic*
        s3=$(du -ch --max-depth=1 /lib/modules/$v* | awk '/total/{print $1}')
    else
        # Estimate sizof of optional headers at 125MB and size of image at 220MB
        if [[ -d "/usr/src/linux-headers-"$v_main ]] ; then
             s2="125M"
        else
             s2="0M"            # Linux Headers are not installed
        fi
        s3="220M"
    fi

    # Strip out "M" provided by human readable option of du and add 3 sizes together
    c=$(( ${s//[^0-9]*} + ${s2//[^0-9]*} + ${s3//[^0-9]*} ))
    s=$(( ${s//[^0-9]*} )) # Strip out M to make " MB" below which looks nicer
    t=$(( t + c ))
    s=$s" MB"
    c=$c" MB"
    d=$(date --date $(stat -c %y $f) '+%b %d %Y') # Last modified date for display
    item_list=("${item_list[@]}" "$i" "$v ! $d ! $s ! $c" off)
done

# Write Kernel version and array index to unsorted file
> ~/.rm-kernels-plain # Empty any existing file.
for (( i=1; i<${#item_list[@]}; i=i+3 )) ; do
    echo "${item_list[i]}|$i" >> ~/.rm-kernels-plain
done

# Sort kernels by version number
sort -V -k1 -t'|' ~/.rm-kernels-plain -o ~/.rm-kernels-sorted

# Strip out keys leaving Sorted Index Numbers
cut -f2 -d '|' ~/.rm-kernels-sorted > ~/.rm-kernels-ndx

# Create sorted array
SortedArr=()
i=1
while read -r ndx; do 
    SortedArr+=($i "${item_list[$ndx]}" "off")
    (( i++ ))
done < ~/.rm-kernels-ndx

rm ~/.rm-kernels-plain ~/.rm-kernels-sorted ~/.rm-kernels-ndx

cmd=(dialog --backtitle "rm-kernels-server - $n Kernels, Total: $t MB excluding: $current_version" \
    --title "Use space bar to toggle kernel(s) to remove" \
    --column-separator "!" \
    --separate-output \
    --ascii-lines \
    --checklist "         Kernel Version  ------  Modified Date /boot Size  Total" 20 70 15)

selections=$("${cmd[@]}" "${SortedArr[@]}" 2>&1 >/dev/tty)

IFS=$OLDIFS

if [ $? -ne 0 ] ; then
    echo cancel selected
    exit 1
fi

i=0
choices=()

for select in $selections ; do
    ((i++))
    j=$(( 1 + ($select - 1) * 3 ))
    choices[i]=$(echo ${SortedArr[j]} | cut -f1 -d"!")
done

i=0
list=""
for choice in "${choices[@]}" ; do
    if [ "$i" -gt 0 ]; then list="$list- "; fi # append "-" from last loop
    ((i++))

    short_choice=$(echo $choice | cut -f1-2 -d"-")
    header_count=$(find /usr/src/linux-headers-$short_choice* -maxdepth 0 -type d | wc -l)

    # If -lowlatency and -generic are purged at same time the _all header directory
    # remains on disk for specific version with no -generic or -lowlatency below.
    if [[ $header_count -lt 3 ]]; then
        # Remove all w.x.y-zzz headers
        list="$list""linux-image-$choice- linux-headers-$short_choice"
    else
        # Remove w.x.y-zzz-flavour header only, ie -generic or -lowlatency
        list="$list""linux-image-$choice- linux-headers-$choice" 
    fi

done

if [ "$i" -gt 0 ] ; then
    apt-get purge $list
fi

HINWEIS: Beim Aufruf dialogder Direktive --ascii-lineswird übergeben, um den erweiterten Zeichensatz sshfür das Zeichnen von Zeilen (der nicht gefällt) durch "+ ----- +" für Zeichenfelder zu ersetzen . Wenn Ihnen dieses Erscheinungsbild nicht gefällt, können Sie die --no-linesDirektive für keine Box verwenden. Wenn Sie nicht verwenden ssh, können Sie das löschen --ascii-linesund Ihre Anzeige wird mit Strichzeichnungszeichen formatiert:

rm-kernels-server line draw


28. Juli 2017 Updates

Die berechnete Größe jedes Kernels wurde entnommen, aus /boot/*kernel_version*denen 5 Dateien mit einer Gesamtgröße von ~ 50 MB stammten. Die Formel wurde geändert, um die Dateien in /usr/src/*kernel_version*und aufzunehmen /lib/modules/*kernel_version*. Die berechnete Größe für jeden Kernel beträgt jetzt ~ 400 MB.

Standardmäßig wird die Größe von Dateien für Linux-Header auf 125 MB und für Linux-Images auf 220 MB geschätzt, da dudies schmerzhaft langsam sein kann, wenn sich die Dateien nicht im Speicher zwischengespeichert befinden. Um die tatsächliche Größe mit zu erhaltendu übergeben Sie einen beliebigen Parameter an das Skript.

Die Summe aller Kernelgrößen (mit Ausnahme der aktuell laufenden Version, die nicht entfernt werden kann) wird jetzt in der Titelleiste angezeigt.

Das Dialogfeld, in dem das Datum des letzten Zugriffs jedes Kernels angezeigt wird . Dieses Datum kann bei Sicherungen oder ähnlichen Vorgängen für alle Kernel massenüberschrieben werden. Das Dialogfeld zeigt jetzt stattdessen das Änderungsdatum an .


5. August 2017 Updates

Die Kernelliste ist jetzt nicht mehr alphanumerisch, sondern nach Kernelversion sortiert.

Eine zusätzliche Spalte wurde hinzugefügt für /boot size. In der grafischen Zenity-Version wechselt die letzte Spalte zwischen "Real Total" und "Est. Total" (geschätzt), je nachdem, ob Parameter 1 übergeben wird oder nicht.

WinEunuuchs2Unix
quelle
Ich kann Ihr Skript nicht verwenden, obwohl ich es gerne ausprobieren würde. Meine Ubuntu-Computer sind meistens Server und ich benutze sie meistens über SSH-Terminalsitzungen. Ihr Skript funktioniert also nicht. (zenity:16439): Gtk-WARNING **: cannot open display:Ich habe derzeit 65 Kernel installiert und denke, ich habe einen guten Testfall.
Doug Smythies
@DougSmythies Ich habe die Forschung mit begann xdialogmit --checklistfür die Auswahl - Kernel in textbasierten Umgebungen Optionen. Es wird eine Weile dauern, bis ich eine alternative Version erstellt habe, da ich bereits ein viel größeres Projekt (Anpassung der Anzeigehelligkeit basierend auf Sonnenaufgang und Sonnenuntergang) habe, um dieses Wochenende Fragen und Antworten zu dokumentieren und zu veröffentlichen.
WinEunuuchs2Unix
Was ist mit Linux-Image-Extra-, Linux-Signed-Image- und Initrd.img-?
Heynnema
OK danke. Ich habe erst vor wenigen Minuten festgestellt, dass die Frage und die Antwort von derselben Person stammen. Nachdem ich das Skript, auf das ich in meinem Kommentar zu der Frage Bezug genommen habe, nie erhalten habe, führe ich lediglich eine globale Bereinigung durch, nachdem ich zur nächsten RC-Kernelserie (Release Candidate) übergegangen bin. Es bedeutet nur, dass im Allgemeinen viele Kernel herumliegen.
Doug Smythies
1
Ich würde dringend davon abraten, gksu geditdies zu verwenden. Erstens wird Ubuntu nicht mehr mit ausgeliefertgksu , und dies kann immer noch Probleme verursachen. Verwenden sudo nanoSie einfach einfach alt , bitte.
Kaz Wolfe