
¿Qué hace el siguiente código?
Lo encontré en Internet, así que lo copié y lo pegué en la terminal, pero cuando instalé un kernel nuevo solo detecta el anterior.
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')
Respuesta1
Rompamos el código uno por uno (para mi sistema):
$ 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
Entonces esto no haría nada:
$ 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')
Como se puede verestuvo muy cerca de eliminar mi metapaquete actual del kernel linux-image-generic 3.13.0.32.38 amd64 Generic Linux kernel image
(gracias a esta última sed '/[0-9]/!d'
línea), lo cual está mal.
En pocas palabras, esta pieza sed
tiene varios problemas. Debes evitarlo para eliminar los núcleos más antiguos.
EDITAR:
Ya dije que el sed
comando tiene problemas. Por motivos de extensión, voy a eliminar las dos últimas líneas con el formulario que realmente debería funcionar en mi escenario actual.
Las dos últimas líneas en forma modificada:
sed -r 's/^[^ ]* *(([a-z]|-)*)(-[a-z]*) *(([0-9]|-)*)\..*/\1-\4\3/'
Entonces:
$ 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/'
Salida:
linux-image-3.13.0.32-generic
¡¡Eso es muy peligroso!!
Ahora muestro lo que esto le haría a mi sistema, ejecutando el comando --dry-run
completo :apt-get remove
$ 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]
Como puede ver, eliminará todos mis núcleos actuales. Tenga en cuenta también que esto es solo una simulación para coincidir con mi escenario actual y que el original sed
se puede mejorar.
** Tenga en cuenta que el código real funcionará si realiza una reboot
actualización posterior del kernel comoOli ya lo mencionó.
EDITAR2:
Aquí hay un script simple pero robusto que considerará todas las situaciones y eliminará los núcleos más antiguos:
#!/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 tiene alguna versión más reciente que la actual, esto le dará una advertencia para que reinicie su computadora primero. También tenga en cuenta que los kernels más antiguos se conservan por una buena razón: si de alguna manera arruina su kernel actual y hace que su sistema sea inestable, entonces debería poder iniciar cualquier kernel más antiguo.
Respuesta2
Este es un esfuerzo por eliminar los kernels que no son el actual.
Hay muchos fragmentos de código que hacen algo como esto yeste no es un buen ejemplo. Podría eliminar fácilmente los kernels más nuevos que los actuales y, por lo tanto, el metapaquete que instala ( linux-generic
et al) si tuviera una actualización y no reiniciara.