#!/bin/bash
# Historique :
# 1.0 : Mode texte uniquement
# 2.0 : Ajout du mode graphique
# 2.1 : Légères modifications cosmétiques
# 2.2 : Support des kernel 3.X, ajout de --keep-prev
# 3.0 : Utilisation de getopts, refonte du mode terminal, ajout d'un lanceur
# 3.1 : Gestion des nouvelles options en mode graphique, mode term par défaut
# 3.2 : Prise en compte des paquets linux-image-extra* et ajout de --version
# 3.3 : Arrêt du script si un noyau > au courant est trouvé, ajout des 4.X
# 3.4 : Correction de : if [ "FORCE_YES" = "VRAI" ] (Ne provoquait qu'un bug d'affichage)
# 3.5 : Calcul de l'espace disque théoriquement libéré
# 3.6 : Correctifs (suppression non fonctionelle en mode graphique)
# 3.7 : Ajout d'un icône et de la dépendance à gnome-sudo
# 3.8 : dpkg -p devient dpkg -s
# 3.9 : Prise en compte des noyaux "signed" et "lowlatency"
# 4.0 : Voir: https://forum.ubuntu-fr.org/viewtopic.php?pid=21218271#p21218271
# 4.1 : Orthographe (merci Lynn), usage de whoami et gksu plus obligatoire
# 4.2 : Utilisation de pkexec, icon ok sur ubuntu 18+, compatible avec les noyaux 5.x
CURRENT_VER=4.2
## Bugs connus
# Une fois les suppressions lancées en mode graphique,
# il n'est pas possible de les interompre
# L'option force-yes ne fonctionne qu'en mode texte
###################
# Fonctions
###################
function clean_exit
{
rm -f /tmp/clean_kernel.tmp
exit $1
}
function display_syntaxe
{
echo " "
echo " Syntaxe : $0 [options]"
echo " Options disponibles : "
echo " -t --term Lance le script en mode console (mode par défaut)"
echo " -g --gui Lance le script en mode graphique"
echo " -k --keep-prev Conserve automatiquement le noyau précédent"
echo " -s --simulate Aucune suppression reelle, simple simulation"
echo " -h --help Affichage de la syntaxe"
echo " -f --force-yes Suppression sans aucune demande de confirmation !"
echo " -v --version Informations sur les versions"
echo " "
echo " Exemple d'utilisation en ligne de commande : sudo kclean -k "
echo " "
}
function remove_kernel
{
echo " "
echo " Suppression en cours :"
echo " "
for i in `grep -v "$KERNEL" /tmp/clean_kernel.tmp`
do
if [ "$SIMULATE" = "VRAI" ]
then
echo "Suppression du paquet $i (simple simulation...) "
else
apt-get remove --yes --purge $i
fi
done
echo " "
echo " -------------- Suppression effectuée ---------------"
echo " "
clean_exit 0
}
# interpretation des parametres
TERMINAL="VRAI"
KEEP_PREV="FAUX"
SIMULATE="FAUX"
HELP="FAUX"
FORCE_YES="FAUX"
VERSION="FAUX"
while getopts ":tgksvf-:" OPT
do
# gestion des options longues avec ou sans argument
[ $OPT = "-" ] && case "${OPTARG%%=*}" in
term) OPT="t" ;;
gui) OPT="g" ;;
keep-prev) OPT="k" ;;
simulate) OPT="s" ;;
help) OPT="h" ;;
force-yes) OPT="f" ;;
version) OPT="v" ;;
*) display_syntaxe ; clean_exit 1 ;;
esac
# puis gestion des options courtes
case $OPT in
t) ;;
g) TERMINAL="FAUX" ;;
k) KEEP_PREV="VRAI" ;;
s) SIMULATE="VRAI" ;;
h) HELP="VRAI" ;;
f) FORCE_YES="VRAI" ;;
v) VERSION="VRAI" ;;
*) display_syntaxe ; clean_exit 1 ;;
esac
done
## Aide
if [ "$HELP" = "VRAI" ]
then
display_syntaxe
clean_exit 0
fi
## Version
if [ "$VERSION" = "VRAI" ]
then
echo " "
echo "kclean version $CURRENT_VER"
head -21 $0 | grep -v bash
clean_exit 0
fi
## Le script a t-il bien ete lance en tant que root ?
if [ `whoami` != "root" -a "$SIMULATE" = "FAUX" ]
then
echo " "
echo " Erreur : Vous devez avoir les droits de root pour supprimer des paquets"
echo " Avez-vous oublié sudo devant le nom du script ?"
echo " "
clean_exit 2
fi
## Traitements communs
KERNEL=`uname -r | cut -d '-' -f 1,2`
dpkg -l | grep linux | grep ubuntu | grep ii | awk '{print $2}' | grep -E '[2-9]\.' >/tmp/clean_kernel.tmp
dpkg -l | grep linux | grep restricted | grep ii | awk '{print $2}' | grep -E '[2-9]\.' >>/tmp/clean_kernel.tmp
dpkg -l | grep linux | grep image| grep ii | awk '{print $2}' | grep -E '[2-9]\.' >>/tmp/clean_kernel.tmp
dpkg -l | grep linux | grep headers | grep ii | awk '{print $2}' | grep -E '[2-9]\.' >>/tmp/clean_kernel.tmp
dpkg -l | grep linux | grep tools | grep ii | awk '{print $2}' | grep -E '[2-9]\.' >>/tmp/clean_kernel.tmp
#On supprime immediatement de la liste le noyau courant :
sed -i -e /$KERNEL/D /tmp/clean_kernel.tmp
#On cherche le noyau precedent
NB_KERNEL=`dpkg -l | grep linux | grep image | grep ^ii | egrep -v "extra|signed|lowlatency" | awk '{print $2}' | grep -E '[2-9]\.' | wc -l`
if [ $NB_KERNEL -eq 1 ]
then
PREVIOUS_V=""
else
PREVIOUS_V=`dpkg -l | grep linux | grep image | grep ^ii | egrep -v "extra|signed|lowlatency" | awk '{print $2}' | grep -E '[2-9]\.' | sort -V | tail -2 | head -1 | cut -d '-' -f3,4`
fi
# On cherche le noyau le plus recent pour le comparer au noyau courant
LAST_KERNEL=`dpkg -l | grep linux | grep image | grep ^ii | egrep -v "extra|signed|lowlatency" | awk '{print $2}' | grep -E '[2-9]\.' | sort -V | tail -1 | cut -d '-' -f 3,4`
######## Mode texte ############
if [ "$TERMINAL" = "VRAI" ]
then
echo " "
echo "Noyau actuellement en cours d'utilisation : $KERNEL"
echo "Par défaut, seul ce noyau est conservé."
echo " "
if [ "$LAST_KERNEL" != "$KERNEL" ]
then
if [ "$FORCE_YES" = "VRAI" ]
then
echo "ATTENTION : Présence de noyau(x) plus récent(s) sur le système."
echo "Ce script va néanmoins poursuivre (utilisation du -f)"
else
echo "ATTENTION : Au moins un noyau plus récent ( $LAST_KERNEL ) a été détecté."
echo "Ce phénomène peut avoir plusieurs causes mais, par securité,"
echo "ce script va s'arrêter."
echo " "
echo "Si vous comprenez exactement ce qui se passe,"
echo "et si vous souhaitez reelement supprimer tous les noyaux"
echo "y compris les plus récents, utilisez l'option -f seule."
clean_exit 4
fi
fi
if [ "$KEEP_PREV" = "VRAI" ]
then
echo "Ce script va tenter de trouver la version précédente du noyau pour la conserver."
if [ "$FORCE_YES" = "FAUX" ]
then
echo "Verifiez les informations fournies avant de valider la suppression."
fi
echo " "
if [ -z "$PREVIOUS_V" ]
then
echo "Aucune version précédente trouvée, il n'y a donc rien à supprimer."
echo "Abandon."
echo " "
clean_exit 0
fi
echo "La version précédemment installée (à conserver) est la version : $PREVIOUS_V"
sed -i -e /$PREVIOUS_V/D /tmp/clean_kernel.tmp
fi
if [ `cat /tmp/clean_kernel.tmp |wc -l` -eq 0 ]
then
echo "Aucun noyau à supprimer."
echo "Abandon."
echo " "
clean_exit 0
fi
#Calcul de l'espace libere
ESPACEKB=0
for i in `grep -v "$KERNEL" /tmp/clean_kernel.tmp`
do
ESPACEKB=$(($ESPACEKB+`dpkg -s $i | grep Installed-Size | awk '{print $2}'`))
done
ESPACEMB=$(($ESPACEKB / 1024))
echo "Les paquets suivants vont être supprimés :"
echo " "
cat /tmp/clean_kernel.tmp | sed -e "s@^@ @g"
echo " "
echo "Cela devrait libérer environ $ESPACEMB MiB d'espace disque"
echo " "
## Mode non interactif
if [ "$FORCE_YES" = "VRAI" ]
then
remove_kernel
fi
## Mode interactif
echo -n " Voulez-vous indiquer manuellement des paquets à conserver ? [o/N] :"
read REP
if [ "$REP" = "o" -o "$REP" = "O" ]
then
echo " Indiquez la liste des paquets à conserver en les séparant par un espace : "
read REP
for i in `echo "$REP"`
do
sed -i -e /$i/D /tmp/clean_kernel.tmp
done
echo " "
echo " Voila la liste des paquets qui seront donc supprimés :"
echo " "
grep -v "$KERNEL" /tmp/clean_kernel.tmp | sed -e "s@^@ @g"
echo " "
fi
echo -n " Voulez-vous supprimer l'ensemble des paquets indiqués ? [o/N] :"
read REP
if [ "$REP" = "o" -o "$REP" = "O" ]
then
remove_kernel
else
echo " "
echo " Abandon de l'opération..."
echo " "
clean_exit 0
fi
else
############### Mode graphique ##################
## On verifie que zenity est installé
which zenity > /dev/null
if [ $? -ne 0 ]
then
echo " "
echo " le mode graphique nécessite zenity pour fonctionner."
echo " Installez zenity ou utilisez uniquement le mode texte."
echo " "
clean_exit 3
fi
## On verifie qu'un display graphique est disponible
if [ -z "$DISPLAY" ]
then
echo " "
echo " Aucun serveur graphique disponible (variable DISPLAY vide)"
echo " Si vous utilisez un serveur en mode texte uniquement,"
echo " vous pouvez utiliser ce logiciel en mode console en tapant:"
echo " "
echo " $0 --term"
echo " "
clean_exit 3
fi
## As t-on bien les droits admin ?
if [ `whoami` != "root" ]
then
zenity --width=600 --height=400 --error --text="Ce programme nécessite les droits root pour fonctioner.\nRelancer-le en tapant : gksudo $0"
clean_exit 2
fi
if [ "$LAST_KERNEL" != "$KERNEL" ]
then
zenity --width=600 --height=400 --error --text="Vous utilisez actuellement le noyau $KERNEL\nOr, au moins un noyau plus récent ( $LAST_KERNEL ) a été détecté.\nCe phénomène peut avoir plusieurs causes mais,\npar securité, ce script va s'arrêter.\n\nSi vous souhaitez réelement supprimer ce (ou ces) noyau(x),\nlancez kclean en ligne de commande."
clean_exit 4
fi
## Faut il conserver le noyau precedent ?
if [ "$KEEP_PREV" = "FAUX" ]
then
zenity --width=600 --height=400 --question --text "Voulez-vous conservez le noyau précédent ?"
if [ $? -eq 0 ]
then
KEEP_PREV="VRAI"
fi
fi
## Y a t-il vraiment des paquets à supprimer ?
## Si il faut conserver le noyau precedent, on le supprime de a liste
if [ "$KEEP_PREV" = "VRAI" -a ! -z "$PREVIOUS_V" ]
then
sed -i -e /$PREVIOUS_V/D /tmp/clean_kernel.tmp
fi
TEXT="Le noyau actuellement utilisé a pour version : $KERNEL.\n"
if [ "$KEEP_PREV" = "VRAI" -a ! -z "$PREVIOUS_V" ]
then
TEXT="$TEXT Le noyau précédent a pour version : $PREVIOUS_V.\n"
fi
TEXT="$TEXT Aucun paquet faisant référence à un noyau plus ancien n'a été trouvé sur le système...\n\nAppuyez sur VALIDER pour quitter le programme."
if [ -z "`grep -v "$KERNEL" /tmp/clean_kernel.tmp`" ]
then
zenity --width=600 --height=400 --info --title "Nettoyage dans les noyaux..." \
--text="$TEXT"
clean_exit 0
fi
## Oui, il y a des paquets à supprimer...
if [ "$FORCE_YES" = "VRAI" ]
then
TEXT="ATTENTION : L'option -f (force-yes) n'est pas prise en compte en mode graphique."
zenity --warning --width=600 --height=400 --title "Nettoyage dans les noyaux..." --text="$TEXT"
fi
LISTE_PAQUET=""
## Construction de la liste des paquets a supprimer pour zenity
ESPACE_TOTAL=0
for i in `grep -v "$KERNEL" /tmp/clean_kernel.tmp`
do
ESPACEKB=`dpkg -s $i | grep Installed-Size | awk '{print $2}'`
ESPACE_TOTAL=$(($ESPACE_TOTAL+$ESPACEKB))
ESPACEMB=$(($ESPACEKB / 1024))
LISTE_PAQUET="$LISTE_PAQUET TRUE $i $ESPACEMB"
done
ESPACE_TOTAL=$(($ESPACE_TOTAL / 1024))
TEXT="Vous utilisez actuellement la version $KERNEL de Linux.\n"
if [ "$KEEP_PREV" = "VRAI" ]
then
TEXT="$TEXT Le noyau précédent a pour version : $PREVIOUS_V, il sera conservé.\n"
fi
TEXT="$TENT En cliquant sur Valider les paquets suivants seront supprimés:"
CHOIX=$(zenity \
--title "Nettoyage dans les noyaux" \
--text="$TEXT" \
--width=700 --height=500 \
--list --print-column="3" --checklist --separator=' ' \
--column="Supprimer" \
--column="Nom des paquets" \
--column="MiB" \
--print-column=2 \
$LISTE_PAQUET )
## Si on clic sur Annuler...
if [ $? -ne 0 ]
then
clean_exit 2
fi
## Sinon
NBSUP=`echo $CHOIX | wc -w`
PROGRES=0
INCREMENT=`expr 100 / $NBSUP`
(
for i in `echo $CHOIX`
do
if [ "$SIMULATE" = "FAUX" ]
then
apt-get remove --purge --yes "$i" >/dev/null 2>&1
fi
PROGRES=$(($PROGRES+$INCREMENT))
echo "$PROGRES"
echo "# Suppression de $i"
done
) |
zenity --progress --width=600 --auto-close --percentage=0 \
--text="Suppression des paquets sélectionnés..."
if [ "$SIMULATE" = "FAUX" ]
then
TEXTE_FINAL="Les paquets sélectionnés ont bien été supprimés.\nSi tout était coché, vous avez libéré $ESPACE_TOTAL MiB sur le disque."
else
TEXTE_FINAL="Mode simulation terminé, aucun paquet supprimé."
fi
zenity --width=600 --height=400 --info --title "Nettoyage dans les noyaux..." \
--text="$TEXTE_FINAL"
clean_exit 0
fi