Forum Astuces.divers comment je vide proprement mon /boot des vieux noyaux installés par ma distrib

Posté par  . Licence CC By‑SA.
Étiquettes :
0
31
mai
2013

Bonjour,

aujourd'hui je viens vous proposer un petit script qui permet de desintaller proprement les vieux noyaux que la distribution a laissé pour nous dans /boot.

perso je le retape à chaque fois, et c'est une oneliner

sudo aptitude purge $(for i in `seq 24 30`;do dpkg -l | grep 3.5.0-$i | awk '{print $2}';done)

si on veut en faire un script autonome à relancer avec monscript.sh version debut fin
on pourrait ecrire le script comme suit

# recupere la liste des paquets à desinstaller à partir des parametres.

# VERSION sera 3.x.y
VERSION=$1

# DEBUT et FIN seront les variantes (le z dans 3.x.y-z de la version du paquet)
DEBUT=$2
FIN=$3

# on fait une boucle sur la sequence comprise entre $DEBUT et $FIN avec l'outil seq
# pour chaque valeur de la boucle, on fait cherche les paquets correspondants avec dpkg -l | grep...
# on filtre cette liste pour ne recuperer que la 2e colonne de la sortie de dpkg avec awk

LISTE=$(for i in `seq $DEBUT $FIN`;do dpkg -l | grep $VERSION-$i | awk '{print $2}';done)

# on demande à aptitude de purger tous les paquets que l'on a listés juste avant.
sudo aptitude purge $LISTE

ce script en onliner fonctionne parfaitement avec ubuntu et debian
la version multiligne n'a pas été testée.

dans les deux cas, on doit pouvoir faire des choses similaires avec les autres distributions quitte à remplacer dpkg et aptitude par les versions de ces distribs (yum, yaourt, etc)

  • # Pourquoi devoir indiquer la version?

    Posté par  (site web personnel) . Évalué à 3.

    Tu pourrais ne garder que les plus récents.

    Si ton /boot n'a pas l'atime désactivé tu peux aussi supprimer ceux qui n'ont pas été utilisés récemment.

    Sur Mandriva/Mageia l'outil de nettoyage des paquets orphelins enlève aussi tous les noyaux sauf celui en cours d'utilisation et le plus récent différent de celui là.

  • # Ubuntu

    Posté par  (site web personnel) . Évalué à 1.

    Salut,

    Sur Ubuntu, depuis raring, cela se fait tout seul. Voir le fichier /etc/apt/apt.conf.d/01autoremove-kernels.

    Peut-être que ce mécanisme sera intégré sur Debian aussi…

    Ensuite, un "apt-get autoremove" supprimera les anciens noyaux, non marqués "autoremove".

    Enfin j'avais constaté ça il y a quelques semaines mais là maintenant les anciens noyaux restent installés sur mon PC et je n'ai pas le temps de creuser le sujet.

    • [^] # Re: Ubuntu

      Posté par  . Évalué à 2.

      c'est pour ca que je fais toujours à la main,
      j'avais constaté à une epoque que le nettoyage se faisait tout seul lors des mises à jours,
      mais apparemment ca ne le fait plus

      comme ca je maitrise quand le faire et pourquoi le faire.

      en passant, je l'ai fait sur ma machine là,
      et je suis passé de 258Mo à 68Mo occupés par /boot en ne gardant que 2 noyaux (le courant et le precedent)

  • # Utile uniquement sous Debian ?

    Posté par  (site web personnel) . Évalué à 2.

    Ce n'est pas nécessaire sous RedHat/Fedora, car yum le gère automatiquement (le nombre de noyaux à garder est configurable), sous ArchLinux il n'y a toujours qu'un noyau installé dans /boot (sous réserve que l'utilisateur n'installe pas des paquets de noyau alternatifs, mais chacun n'installera toujours qu'un noyau dans /boot).

    • [^] # Re: Utile uniquement sous Debian ?

      Posté par  (site web personnel) . Évalué à 5.

      Donc si le nouveau noyau ne boot pas sur ton matos, tu n'as plus le précédent ?

      • [^] # Re: Utile uniquement sous Debian ?

        Posté par  (site web personnel) . Évalué à 1. Dernière modification le 31 mai 2013 à 12:35.

        Sous Arch non tu ne l'as plus en effet.

        Généralement j'installe aussi un LTS pour parer à ce genre de cas (qui arrive rarement mais qui arrive).

      • [^] # Re: Utile uniquement sous Debian ?

        Posté par  . Évalué à 1.

        J'ai bien 2 noyaux disponible pour le boot : Le plus récent et un LTS. Et pourtant quand j'ai installé ArchLinux, il me semble que j'ai rien fais de particulier de ce côté la.

        Ce n'est effectivement pas le précédent, c'est un noyau LTS qui se met à jour indépendamment. C'est parfois un peu lourd pour les MAJ car c'est des paquets qui sont très gros.

  • # À propos de ta syntaxe

    Posté par  (site web personnel) . Évalué à 3.

    Bon, je vais faire mon chieur, mais tu devrais changer quelques trucs niveau habitudes (pour Bash) :

    1) Les backquotes sont un reliquat d'un temps révolu. Remplace-les par $(…)
    2) Même remarque pour la commande seq. Tu peux la remplacer avantageusement par {1..3} par exemple
    3) Quotes! Si tu veux t'éviter des bogues bien piquantes (bash séparer les noms constitués d'espaces entre autres), je te conseille vivement de changer tes appels de variables : "$VAR".
    4) il n'y a pas de première ligne indiquant l'interpréteur ! #!/bin/bash

    Ça donnerait ça (pas testé, mais ça devrait aller tout seul ) :

    #!/bin/bash
    # recupere la liste des paquets à desinstaller à partir des parametres.
    
    # VERSION sera 3.x.y
    VERSION="$1"
    
    # DEBUT et FIN seront les variantes (le z dans 3.x.y-z de la version du paquet)
    DEBUT="$2"
    FIN="$3"
    
    # on fait une boucle sur la sequence comprise entre $DEBUT et $FIN avec l'outil seq
    # pour chaque valeur de la boucle, on fait cherche les paquets correspondants avec dpkg -l | grep...
    # on filtre cette liste pour ne recuperer que la 2e colonne de la sortie de dpkg avec awk
    
    LISTE=$(for i in {"$DEBUT".."$FIN"}; do dpkg -l | grep "$VERSION-$i" | awk '{print $2}'; done)
    
    # on demande à aptitude de purger tous les paquets que l'on a listés juste avant.
    sudo aptitude purge "$LISTE"
    
    
    • [^] # Re: À propos de ta syntaxe

      Posté par  . Évalué à 2.

      amusant, ou pas

      ma version du script fonctionne

      :/tmp$ bash test.sh 3.5.0 31 32
      linux-image-3.5.0-31-generic linux-image-extra-3.5.0-31-generic linux-headers-3.5.0-32 linux-headers-3.5.0-32-generic linux-image-3.5.0-32-generic linux-image-extra-3.5.0-32-generic linux-libc-dev:amd64

      alors que la tienne ne fait rien

      :/tmp$ bash test.sh 3.5.0 31 32

      NB : j'ai remplacé le aptitude purge par un
      echo $LISTE dans mon script
      echo "$LISTE" dans le tiens

      • [^] # Re: À propos de ta syntaxe

        Posté par  (site web personnel) . Évalué à 2.

        J'ai pas de debian sous la main, mais c'est le {..} qui passe pas avec les arguments en variable. Ainsi, for i in {"$a".."$b"} devient for i in "{24..36}", ce qui ne fait qu'une seule boucle, et ne renvoie rien du coup.

        Du coup, je m'excuse pour le seq, car soit tu utilises un $(seq "$a" "$b"), ou $(eval echo "{$a..$b}"). Bash doit évaluer 2 fois la demande.

        Bref, voici la version finale pour le coup (et désolé…) :

        #!/bin/bash
        # recupere la liste des paquets à desinstaller à partir des parametres.
        
        # VERSION sera 3.x.y
        VERSION="$1"
        
        # DEBUT et FIN seront les variantes (le z dans 3.x.y-z de la version du paquet)
        DEBUT="$2"
        FIN="$3"
        
        # on fait une boucle sur la sequence comprise entre $DEBUT et $FIN avec l'outil seq
        # pour chaque valeur de la boucle, on fait cherche les paquets correspondants avec dpkg -l | grep...
        # on filtre cette liste pour ne recuperer que la 2e colonne de la sortie de dpkg avec awk
        
        LISTE=$(for i in $(seq "$DEBUT" "$FIN"); do dpkg -l | grep "$VERSION-$i" | awk '{print $2}'; done)
        
        # on demande à aptitude de purger tous les paquets que l'on a listés juste avant.
        echo "$LISTE"
        
        

        Ça devrait marcher, si tu pouvais confirmer.

        • [^] # Re: À propos de ta syntaxe

          Posté par  . Évalué à 3.

          ca va beaucoup mieux en effet

          :/tmp$ bash test.sh 3.5.0 31 32
          linux-image-3.5.0-31-generic
          linux-image-extra-3.5.0-31-generic
          linux-headers-3.5.0-32
          linux-headers-3.5.0-32-generic
          linux-image-3.5.0-32-generic
          linux-image-extra-3.5.0-32-generic
          linux-libc-dev:amd64

        • [^] # Re: À propos de ta syntaxe

          Posté par  . Évalué à 3.

          Arrêtez avec grep | awk …. On peut facilement se passer de grep et filtrer dans awk.

          • [^] # Re: À propos de ta syntaxe

            Posté par  . Évalué à 2.

            surement, mais j'ai pas encore pris le temps d'apprendre ca.

            j'imagine aussi que je peux faire ma boucle dans awk plutot que dans le shell ?

            • [^] # Re: À propos de ta syntaxe

              Posté par  . Évalué à 2. Dernière modification le 05 juin 2013 à 08:48.

              Non, mais tu peux faire tout le traitement en awk :

              dpkg -l | awk "\$2 ~ /^linux-image/ && \$3 ~ /$1-/ {
                      i=gensub(/$1-(.+)/,\"\\\1\",\"g\",\$3);
                      if (i >= $2 && i < $3) { print \$2 }
                      }" | xargs sudo aptitude purge
              
              

              Bon, à cause des quotes et des mélanges variable shell/awk c'est pas super lisible ; on pourrait faire plutôt :

              dpkg -l | awk -v version=$1 -v from=$2 -v to=$3 '$2 ~ /^linux-image/ && $3 ~ version "-" {
                      i=gensub(version "-(.+)","\1","g",$3);
                      if (i >= from && i <= to) { print $2 }
                      }' | xargs sudo aptitude purge
              
              
              • [^] # Re: À propos de ta syntaxe

                Posté par  . Évalué à 2.

                sauf que du coup tu ne prend que les "linux-image" là ou moi j'enleve aussi les linux-headers et autres paquets liés au noyau version X.Y.Z-T

                • [^] # Re: À propos de ta syntaxe

                  Posté par  . Évalué à 2.

                  Ah mais tu peux le faire facilement dans ma version, c'est juste que je n'avais pas vu que tu voulais matcher plus large… En tous cas, awk c'est bien !

        • [^] # Re: À propos de ta syntaxe

          Posté par  . Évalué à 2.

          J'ai pas de debian sous la main, mais c'est le {..} qui passe pas avec les arguments en variable. Ainsi, for i in {"$a".."$b"} devient for i in "{24..36}", ce qui ne fait qu'une seule boucle, et ne renvoie rien du coup.

          C'est pour ça que bash propose la syntaxe

          for (( EXPR1 ; EXPR2 ; EXPR3 )) ; do COMMANDS ; done

          qui fonctionne comme la boucle for qu'on trouve dans la plupart des langages.

    • [^] # Re: À propos de ta syntaxe

      Posté par  (site web personnel) . Évalué à 4. Dernière modification le 31 mai 2013 à 17:40.

      2) Même remarque pour la commande seq. Tu peux la remplacer avantageusement par {1..3} par exemple

      Surtout pas. C'est un bashisme ça, pas du shell générique.

      4) il n'y a pas de première ligne indiquant l'interpréteur ! #!/bin/bash

      Les vrais hommes savent écrire du vrai shell générique plutôt que d'utiliser Bash par ignorance : #! /bin/sh. Et n'utilisent Bash que quand ils savent qu'ils ont intérêt à utiliser une fonction spécifique de cet interpréteur particulier.

      Réactions possibles au passage de Bash à dash comme shell par défaut par Ubuntu puis Debian :

      • le mec paresseux : qu'à cela ne tienne, je vais remplacer mes shebangs #! /bin/sh par #! /bin/bash comme ça je n'ai aucun effort à faire et je suis sûr que ça marche ;
      • le mec motivé : je vais apprendre à éviter les bashismes, vérifier mes scripts et remplacer les bashismes par leurs équivalents standards, comme ça ce sera optimal.
      • [^] # Re: À propos de ta syntaxe

        Posté par  (site web personnel) . Évalué à 1.

        Sh en mode interactif n'est plus très utilisé. Ce qui fait que tu as tendance à connaitre Bash et Sh si tu fais des scripts (historique, alias, contrôle des processus, etc.)
        Ensuite, les tests mathématiques en Sh, non merci.

        En outre, le /bin/sh est souvent un lien vers /bin/bash dans une partie des distributions (dans mon Archlinux par exemple)

        Enfin, il faut bien avancer un peu. À quand une mise-à-jour de POSIX ?

        Bref, c'est un choix personnel.

        • [^] # Re: À propos de ta syntaxe

          Posté par  . Évalué à 3.

          En outre, le /bin/sh est souvent un lien vers /bin/bash dans une partie des distributions (dans mon Archlinux par exemple)

          bash est notoirement plus lent qu'un shell plus simple comme dash, qui est utilisé en tant que /bin/sh sur Debian et Ubuntu. Si vous écrivez /bin/sh et remplissez votre script de syntaxes spécifiques à bash, il ne fonctionnera pas.
          Aussi, bien que le script de cette entrée de forum concerne un système Linux, les autres systèmes comme OpenBSD n'utilisent pas bash du tout, et vos scripts (ceux qui ne servent pas à supprimer les noyaux Linux inutilisés) pourront ne pas fonctionner dessus non plus.

        • [^] # Re: À propos de ta syntaxe

          Posté par  (site web personnel) . Évalué à 3.

          Ensuite, les tests mathématiques en Sh, non merci.

          Avec test, alias [ ? Si tu trouves ça difficile, c'est mal barré, effectivement.

          En outre, le /bin/sh est souvent un lien vers /bin/bash dans une partie des distributions (dans mon Archlinux par exemple)

          Exact, et c'était le cas sous Debian et Ubuntu, qui sont passés à dash. L'évolution ne va pas vers bash, au contraire, on s'en débarrasse. Pour les scripts, j'entends, pas comme interpréteur interactif.

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.