¿Es seguro utilizar este comando para eliminar núcleos antiguos?

21

Mientras navegaba por Internet para encontrar artículos de Ubuntu, me encontré con este comando:

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

El autor dijo que este es un comando de una sola línea que eliminará todas las versiones anteriores de Linux, ¡dejando solo la actual !

De hecho, estoy buscando ese comando, pero no estoy tan seguro de qué tan seguro es esto. Me gustaría saber:

  • ¿Es seguro ejecutar este comando?
  • ¿Cómo funciona este comando? es decir, explicación de pequeñas partes de un comando tan grande
  • Si este comando tiene un propósito diferente, ¿cuál sería el comando correcto para lograr lo que el autor dice que hace?

Me siento muy confundido y frustrado cuando trato de deducir todo por mí mismo. ¿Cómo funciona este comando ya que contiene numerosas /, |, \, *, y ^personajes que son difíciles de Google para.

¡Estoy buscando una traducción y explicación paso a paso para este comando que no pude encontrar en Internet!

Bhavesh Diwan
fuente
1
Este no parece ser el mismo comando que cita, pero he estado usando el comando en tuxtweaks.com/2010/10/… para eliminar los núcleos antiguos sin ningún problema. Esta página también explica qué hace el comando.
user68186
44
@UriHerrera apt-get autoremoveno sugiere ninguna eliminación de núcleos antiguos para mí. Si no los elimino, se acumularán hasta que mi /bootespacio se agote y las actualizaciones fallen. ¿Tiene una referencia sobre eso que debería hacer esto?
gertvdijk
1
Lo hace para mí, cada vez que hay una nueva actualización para el kernel, dice después que los siguientes paquetes, etc., ya no son necesarios y enumera el kernel anterior que tenía.
Uri Herrera
Un moderador eliminó mi respuesta, así que comento aquí: vea este artículo para obtener una explicación del guión. No veo por qué una parte del guión es en s/^[^ ]* [^ ]* \([^ ]*\).*/\1/lugar de simplemente s/^[^ ]* \([^ ]*\).*/\1/. El guión no es muy robusto o elegante. Por ejemplo, ¿por qué buscar el núcleo actual antes de extraer el nombre del paquete de la salida? En cuanto a una alternativa, sudo apt-get autoremove --purgepurga la mayoría de los núcleos antiguos en alguna versión más reciente de Ubuntu como Xubuntu 15.10.
jarno

Respuestas:

27

Yo diría: no lo use en la forma actual

  1. Hace cambios sin preguntarte. La apt-get -y purgeparte permite que One-liner comience a ejecutar paquetes de purga, sin su confirmación. Si existe algún error en el script, entonces podría ser jodido .

  2. Sin fuente, sin autor. La fuente de esto hace una diferencia aquí. En caso de que provenga de un paquete de sistema completamente probado, podemos rastrear las pruebas que se realizan en él. De una fuente aleatoria, no podemos confiar en él.

  3. dpkg -lcorre bien sin sudo. No veo por qué el autor original pensó que esto era necesario.

Usa el sentido común

Elimine las partes dañinas y omita todo lo que se ejecute como raíz.

Por ejemplo, reduzca a esto:

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

que solo genera cosas y se ejecuta con permisos de usuario regulares . Una vez que esté de acuerdo con la eliminación de estos núcleos, puede adjuntarse | xargs sudo apt-get purge . No tiene la -yopción, intencionalmente, por lo que se le pedirá confirmación sobre los cambios que se realizarán en su sistema.

Explicación

  • dpkg -lEmite la lista de todos los paquetes. En este caso, solo enumerará los paquetes que comiencen con linux-el nombre.
  • |(una tubería) canaliza la salida del comando a la izquierda (lo llamamos stdout) a la entrada del comando a la derecha (lo llamamos stdin).
  • sedes una herramienta para manipular cadenas usando expresiones regulares . En este caso, manipula la salida del comando a la izquierda de la tubería y filtra los paquetes instalados (basándose en lo iidado por dpkg). Incluso se está anidando en este caso. Sería demasiado difícil explicar todo el uso de sedaquí, ya que su uso es muy complicado con las expresiones regulares complejas. (El \(.*\)-\([^0-9]\+\)"es un ejemplo de una expresión regular.
  • Las expresiones regulares se usan mucho para encontrar coincidencias basadas en la expresión que representan. \1es la referencia de reemplazo para hacer una especie de búsqueda y reemplazo universal (haciendo referencia al primer 'hit' con 1). La expresión regular en sí misma no puede hacer ningún daño. Sin embargo, si manipulan la entrada de manera incorrecta, pueden hacer que elimine los paquetes incorrectos o incluso que realice una inyección de shell. En este caso, parece una forma de encontrar el nombre del paquete del núcleo en función de la versión proporcionada por uname -r.
  • uname -r genera la versión actual del núcleo en ejecución.
  • xargsagrega las líneas de la entrada a la izquierda de la tubería como argumentos para el comando. En este caso, las versiones del kernel en cada línea se convierten en una lista separada por espacios horizontales y se agregan al sudo apt-getcomando.
  • sudo apt-get -y purge [packagename] purga (elimina todo) de los paquetes dados (como argumentos).

Alternativas

Probablemente ya se hayan hecho algunas preguntas sobre esto. Los relevantes que encontré hasta ahora:

gertvdijk
fuente
1
cuál será la ruptura del nodo de aspecto aterrador de este comando que es algo como esto /(.*)-([^0-9font>\+)/\1/")"'/d;s/^[^ ] * [^] * ([^] *). * / \ 1 /; /
Bhavesh Diwan
¿El comando mencionado anteriormente en esta respuesta borrará los viejos núcleos con gracia? ¿o aún es mejor apt-get autoremove?
Bhavesh Diwan
44
@ Z9iT Esas son expresiones regulares. Se utilizan para buscar coincidencias en función de la expresión que representan y \1es el control de reemplazo para hacer una especie de búsqueda y reemplazo universal. Para la eliminación de cualquier paquete, me he expresado claramente en mi respuesta (siendo mi opinión): use el sentido común. No permita que un script realice cambios en su sistema automáticamente. Verifica lo que haría. Siempre.
gertvdijk
La alternativa que presenta no purga los respectivos paquetes de encabezado de Linux.
jarno
Luego, simplemente realice un apt-get autoremove, que debería detectar que esos encabezados ya no son necesarios.
ben-Nabiy Derush
7

Solicitó una explicación paso a paso, así que aquí va:

sudo dpkg -l 'linux-*'

Enumera paquetes que comienzan con linux-el nombre del paquete

| sed

y canalizar la lista a sed

"s/\(.*\)-\([^0-9]\+\)/\1/")"'/d;s/^[^ ]* [^ ]* \([^ ]*\).*/\1/;/[0-9]/!d'

que usará una expresión regular muy complicada para editar la lista

| xargs

que canalizará la nueva lista xargs, que la enviará como argumento a

sudo apt-get -y purge

que purgará esos paquetes sin darle la oportunidad de cambiar de opinión.

O quizás sea más exacto decir que enviará esa lista al comando de purga y la dejará así. Si se purga o no algo, y lo que es más importante, exactamente lo que se purga depende de la salida de los comandos anteriores.

¿Es seguro? En este caso, todo depende de qué tan bien comprenda el autor de la publicación donde lo encontró las expresiones regulares y la sedsintaxis. Y hay libros completos sobre ambos temas.

chaskes
fuente
6

Comencé diseccionando los comandos, leyendo la manpágina para cada uno.

  • dpkg -l: enumera los paquetes, por dpkg -l linux-*lo que enumeraría todos los paquetes que comenzaron con linux-(generalmente núcleos).

  • sed: La salida de dpkg -l linux-*se canaliza sedcon varias expresiones regulares que seddecodifica.

  • uname -r unameimprime información del sistema

uname - imprimir información del sistema

El -ridentificador imprime específicamente las versiones del kernel:

-r, --kernel-release imprime la versión del kernel

La salida de uname -rse canaliza sedcon expresiones más regulares, cuya salida se pasa axargs

Por lo tanto, xargstraduce la sedsalida en nombres de paquetes y los pasa a los sudo apt-get purge -yque automáticamente responde 'sí' a todas las indicaciones:

-y, --yes, --assume-yes Automático sí a las indicaciones; asuma "sí" como respuesta a todas las indicaciones y ejecute de forma no interactiva. Si ocurre una situación indeseable, como cambiar un paquete retenido, intentar instalar un paquete no autenticado o eliminar un paquete esencial, entonces apt-get abortará. Elemento de configuración: APT :: Get :: Assume-Yes.

En conjunto, parece que este comando hará lo que quieras, aunque para saber con seguridad tendremos que traducir sedlas expresiones regulares.

Acabo de correr:

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

Aquí hay una captura de pantalla:

ingrese la descripción de la imagen aquí

Todas las versiones antiguas del kernel iirc.

Seth
fuente
¿Cuál es el ejercicio para traducir la expresión de este sed?
Bhavesh Diwan
2
Estoy tratando de entenderlo ahora mismo, podría llevarnos un tiempo;)
Seth
Mira mi respuesta .
jarno
@ Z9iT Fui demasiado vago para copiar la explicación del guión del artículo vinculado a la respuesta, así que supongo que por eso Seth eliminó mi respuesta. Pero creo que el artículo vinculado es lo que estaba buscando en Internet. También le dije una forma más segura de eliminar los núcleos antiguos, aunque conserva 2-3 núcleos por si acaso, y es posible que todavía no funcione en todas las versiones actuales de Ubuntu.
jarno
@jarno Lo eliminé porque Z9iT estaba preguntando acerca de un comando específico , no una forma segura de eliminar núcleos antiguos. Puede que todavía sea relevante, pero en un comentario, no una respuesta :) (como lo hizo)
Seth