meta données pour cette page
  •  

Menageatator

2017-10-26

suppression des noyaux linux inutilisés et encombrants sous debian et ubuntu. Ménage dans /boot

removal of unused linux kernels in debian and ubuntu. /boot cleaning.


On pourrait croire que le problème est réglé depuis longtemps, mais, de temps en temps pour des raisons bizarres, je tombe toujours sur des ordinateurs dont les noyaux ne sont jamais désinstallés par apt ou unattended-upgrades.

Le script ci dessous est très simple, mais aussi très efficace. il considère que tous les noyaux installés sont effaçables sauf :

  • le noyaux utilisé
  • les noyaux provenant de paquet on hold
  • le dernier
  • l'avant dernier si on tourne en ce moment sur le dernier
  • les noyaux à moitié installé ou cassés

Il conservera donc au moins deux noyaux, dont le dernier et celui en cours.

cliquer sur le nom du script ci dessous pour le télécharger.

One might think this problem has been solved long ago. But for some weird and unknown reasons, I still meet people whose computers are cluttered whith old kernels. What is unattended-upgrade doing ? mystery.

The script below is very simple but also very effective. The idea is that all kernels can be removed but :

  • the current one
  • kernels explicitely on hold
  • the most recent one
  • the last but one when the current kernel is the most recent one
  • half installed or broken kernels

It keeps at least two kernels : the running one and, apart from this, the most recent.

Click on the script name to download it

menageatator
#! /bin/bash
# encoding: utf-8
# vim: se ts=2 sw=2 et:
 
# menageatator: Remove unneeded linux kernel from debuntu systems
# http://schplurtz.free.fr/wiki/schplurtziel/menageatator
#  
#               Copyright Schplurtz Le Déboulonné, 2016, 2017, 2019
#  
#                  Schplurtz le Déboulonné <Schplurtz@laposte.net>
#  
#                FRENCH                |            ENGLISH
#  ------------------------------------+--------------------------------------
#  Ce logiciel est un programme        | This software is a computer program
#  informatique servant à supprimer    | whose purpose is to automatically
#  automatiquement les noyaux non      | remove unused kernels from ubuntu
#  utilisés des systèmes ubuntu ou     | or Debian GNU/Linux systems.
#  debian GNU/linux.                   |
#                                      |
#  Ce logiciel est régi par la licence | This software is governed by the
#  CeCILL soumise au droit français et | CeCILL license under French law and
#  respectant les principes de         | abiding by the rules of
#  diffusion des logiciels libres.     | distribution of free software.  You
#  Vous pouvez utiliser, modifier      | can  use, modify and/ or
#  et/ou redistribuer ce programme     | redistribute the software under the
#  sous les conditions de la licence   | terms of the CeCILL license as
#  CeCILL telle que diffusée par le    | circulated by CEA, CNRS and INRIA
#  CEA, le CNRS et l'INRIA sur le site | at the following URL
#  "http://www.cecill.info/".          | "http://www.cecill.info/".
#                                      |
#  En contrepartie de l'accessibilité  | As a counterpart to the access to
#  au code source et des droits de     | the source code and  rights to
#  copie, de modification et de        | copy, modify and redistribute
#  redistribution accordés par cette   | granted by the license, users are
#  licence, il n'est offert aux        | provided only with a limited
#  utilisateurs qu'une garantie        | warranty  and the software's
#  limitée.  Pour les mêmes raisons,   | author,  the holder of the economic
#  seule une responsabilité restreinte | rights,  and the successive
#  pèse sur l'auteur du programme,  le | licensors  have only  limited
#  titulaire des droits patrimoniaux   | liability.
#  et les concédants successifs.       |
#                                      |
#  A cet égard  l'attention de         | In this respect, the user's
#  l'utilisateur est attirée sur les   | attention is drawn to the risks
#  risques associés au chargement,  à  | associated with loading,  using,
#  l'utilisation,  à la modification   | modifying and/or developing or
#  et/ou au développement et à la      | reproducing the software by the
#  reproduction du logiciel par        | user in light of its specific
#  l'utilisateur étant donné sa        | status of free software, that may
#  spécificité de logiciel libre, qui  | mean  that it is complicated to
#  peut le rendre complexe à manipuler | manipulate,  and  that  also
#  et qui le réserve donc à des        | therefore means  that it is
#  développeurs et des professionnels  | reserved for developers  and
#  avertis possédant  des              | experienced professionals having
#  connaissances  informatiques        | in-depth computer knowledge. Users
#  approfondies.  Les utilisateurs     | are therefore encouraged to load
#  sont donc invités à charger  et     | and test the software's suitability
#  tester  l'adéquation  du logiciel à | as regards their requirements in
#  leurs besoins dans des conditions   | conditions enabling the security of
#  permettant d'assurer la sécurité de | their systems and/or data to be
#  leurs systèmes et ou de leurs       | ensured and,  more generally, to
#  données et, plus généralement, à    | use and operate it in the same
#  l'utiliser et l'exploiter dans les  | conditions as regards security.
#  mêmes conditions de sécurité.       |
#                                      |
#  Le fait que vous puissiez accéder à |  The fact that you are presently
#  cet en-tête signifie que vous avez  |  reading this means that you have
#  pris connaissance de la licence     |  had knowledge of the CeCILL license
#  CeCILL, et que vous en avez accepté |  and that you accept its terms.
#  les termes.                         |
 
# Yeah I know. Could use ruby/perl/ocam/lua/python/whatever and less pipes.
# Could use array, associative arrays etc... Just prefering simplicity,
# clarity and possibility to run with dumb^Wsimple shells. 
 
# 
# Whatever happens :
#   keep the current kernel
#   keep the most recent kernel correctly installed
#   keep all kernels that are on hold
# if current = most recent, keep the next most recent kernel
# 
# remove anything else.
 
 
IFS="$(printf ' \t')
"
# /sbin and /usr/sbin are usually not in cron PATH. add them
# if they're not present as dpkg will need commands there.
case "$PATH" in
(*:/usr/sbin|/usr/sbin:*|*:/usr/sbin:*) : ;;
(*) PATH="${PATH}:/usr/sbin" ;;
esac
case "$PATH" in
(*:/sbin|/sbin:*|*:/sbin:*) : ;;
(*) PATH="${PATH}:/sbin" ;;
esac
 
set -e # Stop on any error.
 
version() {
  sed -e "s/${1}-//"           # remove prefix
}
no_suffix() {
  sed -e 's/-[a-zA-Z_]*$//'    # remove suffix. (-generic, -lowlatency etc...)
}
 
reject() {
  grep -v "$@"
}
 
dpkg_query() {
# dpkg sorts alphabetically. to avoid problematic order, explicitly sort
# on version number.
#            before sorting          |           After sorting
# ii  linux-image-3.13.0-100-generic | ii  linux-image-3.13.0-95-generic
# ii  linux-image-3.13.0-101-generic | ii  linux-image-3.13.0-98-generic
# ii  linux-image-3.13.0-95-generic  | ii  linux-image-3.13.0-100-generic
# ii  linux-image-3.13.0-98-generic  | ii  linux-image-3.13.0-101-generic
 
# old dpkg-query (from ubuntu 12.04 lucid for example) don't support
# ${db:Status-Abbrev}. We have to use ${Status} that's a real pain.
# We have to convert things like "deinstall ok config-files" to
# "rc "
# examples :
#     install ok installed linux-image-3.2.0-23-generic
#     unknown ok not-installed linux-image-3.2.0-23-generic
#     deinstall ok config-files linux-image-3.2.0-23-generic
#     hold ok installed linux-image-3.2.0-23-generic
# The sed script does this :
#   1) rewrite deinstall to removed
#   2) replace the first 3 word by their initials in changing order
#      fe "unknown ok not-installed" becomes "uno" (2 and 3 are swapped)
#   3) in 3rd column, replace "o" by " " 
# Also we are not interested in uninstalled kernels, so we filter
# out the kernels that dpkg has never touched : /^un /
 
  dpkg-query -W -f '${Status} ${package}\n' "$@" 2>/dev/null |
    sed -e 's/^deinstall/removed/
            s/^\(.\)[^ ]* *\(.\)[^ ]* *\(.\)[^ ]* */\1\3\2 /
            s/^\(..\)o/\1 /
           ' |
    reject '^un ' |
    sort -k 2,2V # always return list sorted by version number
}
 
_apt_get() {
  # args >&2 apt-get "$@"
  apt-get "$@"
}
ARGV=( "$@" ) # keep command line args for final apt-get command...
 
        linux_vers_tpl='[0-9]*.[0-9]*.[0-9]*-[0-9]*'
      linux_images_tpl="linux-image-${linux_vers_tpl}"
linux_images_extra_tpl="linux-image-extra-${linux_vers_tpl}"
     linux_headers_tpl="linux-headers-${linux_vers_tpl}"
     linux_modules_tpl="linux-modules-${linux_vers_tpl}"
 
# list of all linux-image packages dpkg is aware of
linux_img=$( dpkg_query "$linux_images_tpl" )
 
# Get the list of packages NOT to remove :
# onhold, current, latest, almost_latest
onhold= current= latest= almost_latest=
 
current=$(                        # This one is easy.
  uname -r |                      # get current version
  no_suffix                       # just the version, not the kind
)
 
onhold=$(
  echo "$linux_img" |             # list linux images
  grep ^h |                       # keep only those on hold
  awk '{ print $2 }' |            # keep package name only
  version linux-image |           # just need the version part of the name
  no_suffix                       # just the version, not the kind
)
 
latest=$(
  echo "$linux_img" |             # list linux images
  grep ^.i |                      # only consider correctly installed packages
  tail -1  |                      # keep last one
  awk '{ print $2 }' |            # keep package name only
  version linux-image |           # just need the version part of the name
  no_suffix                       # just the version, not the kind
)
 
if test "$latest" = "$current"
then
  almost_latest=$(
    echo "$linux_img" |           # list linux images
    grep ^.i |                    # only consider correctly installed packages
    tail -2  |                    # keep last two
    head -1  |                    # keep first one (that is the 2nd most recent)
    awk '{ print $2 }' |          # keep package name only
    version linux-image |         # just need the version part of the name
    no_suffix                     # just the version, not the kind
  )
fi
 
# build list and (grep -e args) of kernels to keep
set -- 
for version in $onhold $current $latest $almost_latest
do
  set -- ${1+"$@"} -e "$version"
done
#OFF#green="$*"
#OFF## 32 vert; 33 brown
#OFF#set -- -e '/^h/s/.*/&/' $(
#OFF#  printf '%s\n' $green |
#OFF#  awk '
#OFF#    /^-e$/ { print; next }
#OFF#    { print "/" $1 "/s/.*/&/" }
#OFF#  '
#OFF#  )
#OFF#
#OFF#set -x
#OFF#  dpkg_query \
#OFF#    "$linux_images_tpl" \
#OFF#    "$linux_images_extra_tpl" \
#OFF#    "$linux_headers_tpl" |        # list linux images, images-extra, headers
#OFF#    sed "$@"
#OFF#
#OFF#exit
 
# build list of kernels to remove
set -- $(
  dpkg_query \
    "$linux_images_tpl" \
    "$linux_images_extra_tpl" \
    "$linux_headers_tpl" \
    "$linux_modules_tpl" |        # list linux images, images-extra, headers, modules
  reject '^h' |                   # filter out packages on hold
  reject "$@" |                   # filter out those we keep
  awk '{ print $2 }'              # just keep name
)
 
# If there are kernels to remove, remove them
{ test $# -gt 0 && _apt_get "${ARGV[@]}" purge "$@" ; } || :
 
# Given this list of kernel,
# ii  linux-image-3.13.0-93-generic
# ii  linux-image-3.13.0-95-generic
# ii  linux-image-3.13.0-96-generic
# ii  linux-image-3.13.0-98-generic
# ii  linux-image-3.13.0-100-generic
# ii  linux-image-3.13.0-101-generic
# ii  linux-image-3.13.0-103-generic
#
# and if we are running 3.13.0-95, this script
# performs these removal :
# apt-get purge linux-image-3.13.0-93-generic linux-image-3.13.0-96-generic linux-image-3.13.0-98-generic linux-image-3.13.0-100-generic linux-image-3.13.0-101-generic

Utilisation / Usage

sudo menageatator

Si vous êtes brave et ne voulez pas confirmer les choix de menageatator

If you are brave and don't want to confirm menageatator choices

sudo menageatator -y