Que fait cette instruction «apt-get remove»?

10

Que fait le code suivant?

Je l'ai trouvé sur Internet, je l'ai donc copié et collé dans le terminal, mais lorsque j'ai installé un nouveau noyau, il ne détecte que l'ancien.

sudo apt-get remove --purge $(dpkg -l 'linux-image-*' | sed '/^ii/!d;/'"$(uname -r | sed "s/\(.*\)-\([^0-9]\+\)/\1/")"'/d;s/^[^ ]* [^ ]* \([^ ]*\).*/\1/;/[0-9]/!d')
medo_alouane
la source
La deuxième partie est une expression régulière, définissant l'apparence du nom de fichier mais pas exactement de quel nom de fichier il s'agit. S'agit-il d'installer un noyau qui est votre objectif ou de savoir exactement ce que la commande supprime?
Niklas Lindskog
Ce code n'installera aucun noyau, mais supprimez- les! Je ne vois pas exactement ce que fait cette commande sed, mais elle traite la sortie de dpkg -l 'linux-image-*', qui répertorie tous les packages du noyau installés et en filtre certains pour les supprimer apt-get remove.
Byte Commander
16
Une très bonne règle de base: si vous ne savez pas ce que fait un code, ne mettez pas ce code dans Terminal jusqu'à ce que quelqu'un qui sache ce qu'il vous dit. Si vous essayez d'obtenir le noyau le plus à jour, vous voudrez peut-être consulter askubuntu.com/questions/119080/… au lieu d'utiliser un code que vous ne comprenez pas.
Colonel Trogdor
Les vieux noyaux assis sur le disque ne posent aucun problème, sauf pour occuper de l'espace disque et update-grubralentir (le paquet après). Si vous craignez de ne pas avoir réellement démarré le noyau vers lequel vous tentiez de mettre à niveau, puis de l'exécuter uname -a, ou mêmedmesg | less
Peter Cordes
7
"Je l'ai trouvé sur Internet, je l'ai donc copié et collé dans le terminal" NON NON NON NON NON. Vous finirez par faire des choses horribles par accident. L'exécution de code que vous ne comprenez pas entraîne des choses terribles comme frapper votre système et les chiots se faire botter.
Journeyman Geek

Réponses:

12

Brisons le code un par un (pour mon système):

$ dpkg -l 'linux-image-*'
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name                          Version             Architecture        Description
+++-=============================-===================-===================-================================================================
un  linux-image-3.0               <none>              <none>              (no description available)
ii  linux-image-3.13.0-32-generic 3.13.0-32.57        amd64               Linux kernel image for version 3.13.0 on 64 bit x86 SMP
ii  linux-image-extra-3.13.0-32-g 3.13.0-32.57        amd64               Linux kernel extra modules for version 3.13.0 on 64 bit x86 SMP
ii  linux-image-generic           3.13.0.32.38        amd64               Generic Linux kernel image


$ dpkg -l 'linux-image-*' | sed '/^ii/!d'
ii  linux-image-3.13.0-32-generic                         3.13.0-32.57                                        amd64        Linux kernel image for version 3.13.0 on 64 bit x86 SMP
ii  linux-image-extra-3.13.0-32-generic                   3.13.0-32.57                                        amd64        Linux kernel extra modules for version 3.13.0 on 64 bit x86 SMP
ii  linux-image-generic                                   3.13.0.32.38                                        amd64        Generic Linux kernel image


$ uname -r | sed 's/\(.*\)-\([^0-9]\+\)/\1/'
3.13.0-32



$ dpkg -l 'linux-image-*' | sed '/^ii/!d' | sed "/$(uname -r | sed 's/\(.*\)-\([^0-9]\+\)/\1/')/d"
ii  linux-image-generic                                   3.13.0.32.38                                        amd64        Generic Linux kernel image



$ dpkg -l 'linux-image-*' | sed '/^ii/!d' | sed "/$(uname -r | sed 's/\(.*\)-\([^0-9]\+\)/\1/')/d" | sed 's/^[^ ]* [^ ]* \([^ ]*\).*/\1/'
linux-image-generic



$ dpkg -l 'linux-image-*' | sed '/^ii/!d' | sed "/$(uname -r | sed 's/\(.*\)-\([^0-9]\+\)/\1/')/d" | sed 's/^[^ ]* [^ ]* \([^ ]*\).*/\1/' | sed '/[0-9]/!d'
## No output

Donc, cela ne ferait rien:

$ sudo apt-get remove --purge $(dpkg -l 'linux-image-*' | sed '/^ii/!d;/'"$(uname -r | sed "s/\(.*\)-\([^0-9]\+\)/\1/")"'/d;s/^[^ ]* [^ ]* \([^ ]*\).*/\1/;/[0-9]/!d')

Comme vous pouvez le voir, il était très proche de supprimer mon méta-paquet du noyau actuel linux-image-generic 3.13.0.32.38 amd64 Generic Linux kernel image (grâce à cette dernière sed '/[0-9]/!d'ligne), ce qui est faux.

En un mot, ce morceau de seda plusieurs problèmes. Vous devez l'éviter pour supprimer vos anciens noyaux.

ÉDITER:

J'ai déjà dit que la sedcommande avait des problèmes. Par extension, je vais supprimer les deux dernières lignes avec le formulaire qui devrait réellement fonctionner dans mon scénario actuel.

Les deux dernières lignes sous une forme modifiée:

sed -r 's/^[^ ]* *(([a-z]|-)*)(-[a-z]*) *(([0-9]|-)*)\..*/\1-\4\3/'

Donc:

$ dpkg -l 'linux-image-*' | sed '/^ii/!d;/'"$(uname -r | 
sed "s/\(.*\)-\([^0-9]\+\)/\1/")"'/d' | 
sed -r 's/^[^ ]* *(([a-z]|-)*(-[a-z]*) *(([0-9]|\.|-)*)\..*/\1\-\4\3/'

Outpus:

linux-image-3.13.0.32-generic

C'est très honteux !!

Maintenant, montrez ce que cela ferait à mon système, avec --dry-runla apt-get removecommande complète :

$ sudo apt-get remove --dry-run $(dpkg -l 'linux-image-*' | 
sed '/^ii/!d;/'"$(uname -r | sed "s/\(.*\)-\([^0-9]\+\)/\1/")"'/d' | 
sed -r 's/^[^ ]* *(([a-z]|-)*)(-[a-z]*) *(([0-9]|\.|-)*)\..*/\1\-\4\3/')


Reading package lists... Done
Building dependency tree       
Reading state information... Done
Note, selecting 'linux-image-3.13.0-32-generic' for regex 'linux-image-3.13.0.32-generic'
The following package was automatically installed and is no longer required:
  linux-headers-generic
Use 'apt-get autoremove' to remove it.
The following packages will be REMOVED:
  linux-generic linux-image-3.13.0-32-generic
  linux-image-extra-3.13.0-32-generic linux-image-generic
0 upgraded, 0 newly installed, 4 to remove and 0 not upgraded.
Remv linux-generic [3.13.0.32.38]
Remv linux-image-generic [3.13.0.32.38]
Remv linux-image-extra-3.13.0-32-generic [3.13.0-32.57]
Remv linux-image-3.13.0-32-generic [3.13.0-32.57]

Comme vous le voyez, cela supprimera tous mes noyaux actuels, notez également qu'il ne s'agit que d'une simulation pour correspondre à mon scénario actuel et que l'original sedpeut être amélioré.

** Notez que le code réel fonctionnera si vous effectuez une rebootmise à niveau après le noyau comme Oli l'a déjà mentionné .

EDIT2:

Voici un script simple mais robuste qui prendra en compte toutes les situations et supprimera les noyaux plus anciens réels:

#!/bin/bash
kernels=( $(grep -Po "^linux-image-[^-]+-[^-]+-generic\b" < <(dpkg --get-selections)) )
cur_rel=$(grep -Po ".*(?=-[a-z]*$)" < <(uname -r))

for kernel in "${kernels[@]}"; do
    ker_rel=$(grep -Po "[0-9].*(?=-[a-z]*)" <<< "$kernel")
    dpkg --compare-versions "$ker_rel" gt "$cur_rel" && { echo "Please Restart your computer first"; break; }
    dpkg --compare-versions "$ker_rel" lt "$cur_rel" && sudo apt-get remove "$kernel"
done

Si vous avez une version plus récente que la version actuelle, cela vous donnera un avertissement pour redémarrer votre ordinateur en premier. Notez également que les noyaux plus anciens sont préservés pour une bonne raison qui est que si vous gâchez en quelque sorte votre noyau actuel rendant votre système instable, vous devriez pouvoir démarrer dans n'importe quel noyau plus ancien.

heemayl
la source
Attends, quoi? Vous remplacez le code de travail d'origine par un autre code que vous pensez "devrait (en fait) être là", observez que votre code "fixe" est cassé et supprimerait votre noyau actuel, et ainsi conclure que le code d'origine est " très honteux !! "? WTF? -1.
Ilmari Karonen
Il y a certainement des raisons valables de critiquer le code original, comme indiqué par exemple dans la réponse d'Oli, et je suis sûr que le code sed pourrait être rendu plus robuste. Mais ce fait demeure que, dans des circonstances normales (par exemple, vous avez redémarré après votre dernière mise à niveau du noyau), le code d'origine fonctionne, contrairement à votre version modifiée.
Ilmari Karonen
1
Tout d'abord, vous ne devez pas utiliser le dernier mot que vous avez utilisé ... maintenant, avez-vous réellement exécuté le code réel? retirer la apt-getpièce et quelle sortie avez-vous obtenue?
heemayl
@IlmariKaronen: eh bien, je suis deuxième avec vous sur certains points, j'ai modifié la réponse ..
heemayl
Pourquoi, oui, je ne lance votre commande modifiée (la version qui ne tombe pas en panne en raison d'une parenthèse manquante après (([a-z]|-)*, qui est) sans la apt-getpartie avant de la critiquer. Sur mon système, il affiche les lignes suivantes: linux-image-3.13-, linux-image-3.13-, linux-image-extra-3.13-, linux-image-extra-3.13-, linux-image-3.13.0.49-generic. Est-ce vraiment ce que vous vouliez? (De plus, des points bonus si vous pouvez déterminer quels noyaux j'ai réellement installés.)
Ilmari Karonen
12

Il s'agit d'un effort pour supprimer les noyaux qui ne sont pas ceux actuels.

Il y a beaucoup de morceaux de code qui font quelque chose comme ça et ce n'est pas un bon exemple . Il pourrait facilement supprimer les noyaux plus récents qu'actuellement et donc le méta-package qui s'installe ( linux-genericet al) si vous aviez une mise à niveau et que vous ne redémarriez pas.

Oli
la source
2
Et ce n'est pas du tout une bonne idée. Ces noyaux plus anciens sont conservés pour raison, par défaut, il n'y en a que 2 anciens et un actuel.
Barafu Albino