Script para eliminar los kernels antiguos

A medida que vamos actualizando nuestro linux (Ubuntu en mi caso) van quedando diferentes versiones del kernel. La idea de este script que uso es principalmente limpiar el sistema de kernels innecesarios, y también acortar la lista de arranque (grub o burg).

Este script debe ejecutarse en modo root, por ejemplo usando el comando sudo:

sudo ./script

El script verifica que exista al menos dos kernels, y de no ser así no eliminarán nada, lo cual permite ejecutarlos en cualquier momento o incluso automatizar su ejecución, sin tener ninguna información previa respecto a la cantidad de kernels en el sistema.

Este script no funciona en bash v4.1 (Ubuntu 10 o anterior), pero sí lo hacen en bash v4.2 (Ubuntu 12 o posterior).

Tan solo basta configurarlo cambiando los parámetros que en él se indican en la sección config (abrirlo con un editor de texto):

Modo de funcionamiento, dejar solo un kernel o los últimos dos (descripción detallada más abajo):

  • MODO=1 : KernelCleaner1
  • MODO=2 : KernelCleaner2

Modo de mostrar mensajes: por consola, log y/o notificación

  • CONSOLA=0 : No muestra mensajes en consola
  • CONSOLA=1 : Muestra mensajes en consola
  • LOG=0 : No guarda mensajes
  • LOG=1 : Guarda mensajes en /var/log/syslog
  • POPUP=0 : No muestra mensajes gráficos
  • POPUP=1 : Muestra mensajes gráficos

Si se configuran todos los modos en 0, el programa funcionará en forma silenciosa y no mostará ningún mensaje. El modo LOG emplea el comando logger. El modo notificación (POPUP) requiere notify-send, dado que usa notify-osd.

  • Determinar si se mostrará el encabezado en pantalla (presentación del programa) o no:
    • ENCABEZADO=0 : No muestra encabezado
    • ENCABEZADO=1 : Muestra encabezado (solo por consola o notificación)
  • (v > 3.2) Se incorporó el modo testeo o debbug, que permite ejecutar el script sin aplicar cambios al sistema
    • NORUN=0 : Modo normal
    • NORUN=1 : Modo de prueba

Eso es todo lo que puede configurarse. Por defecto esta activo el modo KernelCleaner2, mostrando mensajes y encabezado solo por consola.

#!/bin/bash
# Config
############################################################
declare -r VERSION="3.2"
declare -r TITULO="KernelCleaner"

# MODO=1 : KernelCleaner1
# MODO=2 : KernelCleaner2
declare -ir MODO=2

# CONSOLA=0 : No muestra mensajes en consola
# CONSOLA=1 : Muestra mensajes en consola
declare -ir CONSOLA=1

# LOG=0 : No guarda mensajes
# LOG=1 : Guarda mensajes en /var/log/syslog
#		(requiere comando logger)
declare -i LOG=0

# POPUP=0 : No muestra mensajes gráficos
# POPUP=1 : Muestra mensajes gráficos (requiere notify-send)
declare -i POPUP=0

# ENCABEZADO=0 : No muestra encabezado
# ENCABEZADO=1 : Muestra encabezado (solo por consola)
declare -ir ENCABEZADO=1

# Config avanzada
############################################################
# NORUN=1 : Modo de prueba o debug, no elimina kernels ni
#		modifica grub/burg
# NORUN=0 : Modo normal
declare -ir NORUN=0
############################################################

# Variables internas, no editar
############################################################
declare -r KRNLST="`tempfile -p "kc${MODO}-"`"
declare -ir EXIT_FAILURE=1
declare -ir EXIT_SUCCESS=0
declare -i ECODE=0
declare -r TMPFILE="`tempfile -p "kc${MODO}-"`"
############################################################

# Funciones
############################################################
function requisitos {
	# Verifica requisitos, invalida config de usuario

	# logger
	logger -V > /dev/null 2>&1
	if [ $? -ne 0 ]; then LOG=0; fi

	# notify-send
	notify-send -v > /dev/null 2>&1
	if [ $? -ne 0 ]; then POPUP=0; fi
}

function _econ {
	if [ ${CONSOLA} -eq 1 ]; then
		echo "$@"
	fi
}

function _elog {
	if [ ${LOG} -eq 1 ]; then
		logger -t "${TITULO} v${VERSION}" "$@"
	fi
}

function _epop_l {
	if [ ${POPUP} -eq 1 ]; then
		notify-send "$1" "$2"
	fi
}

function _epop {
	_epop_l "${TITULO} v${VERSION}" "$@"
}

function _e {
	_econ "** $@"
	_elog "$@"
	_epop "$@"
}

function _ee {
	if [ ${CONSOLA} -eq 1 ]; then
		cat ${TMPFILE}
	fi
	if [ ${LOG} -eq 1 ]; then
		cat ${TMPFILE} | logger -t "${TITULO} v${VERSION}"
	fi
	if [ ${POPUP} -eq 1 ]; then
		cat ${TMPFILE} | xargs -0 notify-send "${TITULO} v${VERSION}"
	fi
}

function print_header {
	if [ ${ENCABEZADO} -eq 1 ]; then
		# No loggeo encabezado
		_econ
		_econ "KernelCleaner modo ${MODO} v${VERSION} by HacKan & CuBa co."
		_econ "http://www.hackan.com.ar/2012/02/bash-script-eliminar-kernels-antiguos"
		_econ
		_epop_l "KernelCleaner modo ${MODO} v${VERSION} by HacKan & CuBa co." "http://www.hackan.com.ar/2012/02/bash-script-eliminar-kernels-antiguos"
	fi
}

function print_mode {
	if [ ${NORUN} -ne 0 ]; then
		_e "ATENCION: Modo de prueba.  No se realizan cambios en el sistema"
	fi
}

function desinstalar {
	_e "Desinstalando $1..."
	if [ ${NORUN} -eq 0 ]; then
		apt-get -qy remove $1 > ${TMPFILE} 2>&1
	else
		apt-get -qys remove $1 > ${TMPFILE} 2>&1
	fi
	_ee
	_e "Hecho"
}

function get_kernel_list {
	if [ ${MODO} -eq 1 ]; then
		# kc1
		ls /boot/ | grep vmlinuz | sed 's@vmlinuz-@linux-image-@g' | grep -v `uname -r` > ${KRNLST}
	else
		#kc2
		ls /boot/ | grep vmlinuz | sed 's@vmlinuz-@linux-image-@g' | sed  '$d' | sed '$d' > ${KRNLST}
	fi
}

function actualizar_grub {
	_e "Actualizando GRUB..."
	if [ ${NORUN} -eq 0 ]; then
		update-grub -o ${TMPFILE}
		_ee
	fi
	_e "Hecho"
}

function actualizar_burg {
	burg-probe -V > /dev/null 2>&1
	if [ $? -eq 0 ]; then
		_e "Actualizando BURG..."
		if [ ${NORUN} -eq 0 ]; then
			update-burg -o ${TMPFILE}
			_ee
		fi
		_e "Hecho"
	fi
}

function cleanup {
	rm -f ${KRNLST}
	rm -f ${TMPFILE}
}
############################################################

# Programa
############################################################
requisitos
print_header
print_mode

if [ "`whoami`" = "root" ]; then
	get_kernel_list
	if [ -s ${KRNLST} ]; then
		for i in `cat ${KRNLST}`; do
			desinstalar $i
			i="`echo $i|sed 's@image@headers@g'`"
			desinstalar $i
		done
		actualizar_grub
		actualizar_burg
	else
		_e "No hay kernels antiguos que eliminar"
	fi
else
	_e "Usted no es root"
	_e "Ejecute $0 como root"
	ECODE=${EXIT_FAILURE}
fi
cleanup
_e "Terminado"
exit ${ECODE}
############################################################