#!/usr/bin/env bash
set -o pipefail
cleanup()
{
rm -f "${tmp_container[@]}"
}
insert_date()
{
while read
do
local date_value
date_value="$(date +"%b %d %T %s.%N")"
echo "${date_value} ${REPLY}"
done
}
fatal_error_handler()
{
local result="$?"
local p_message="$1"
local pid="${BASHPID}"
(exit "${result}") ||
{
(
cd "$(dirname "${BASH_SOURCE[1]}")"
echo -n "${FUNCNAME[0]}: $(echo | insert_date)${PWD}/${BASH_SOURCE[1]##*/}:${BASH_LINENO[0]} ${FUNCNAME[1]}() PID(${pid})"
)
[ "${p_message}" != "" ] && echo -n " ${p_message}"
echo
return "${result}"
} >&2
}
version_test_gt()
{
local version_a="$1"
local version_b="$2"
dpkg --compare-versions "${version_a}" gt "${version_b}"
}
get_current_kernel_version()
{
local p_dpkg_output="$1"
local current_kernel_version
current_kernel_version="linux-image-$(uname -r)"
current_kernel_version="$(awk '$2=="'${current_kernel_version}'" {print $3}' <<< "${p_dpkg_output}")" || fatal_error_handler || return
[ "${current_kernel_version}" != "" ] || fatal_error_handler || return
echo "${current_kernel_version}"
}
is_gui_required()
{
if ! tty &> /dev/null
then
echo "true"
else
echo "false"
fi
}
main()
{
local dpkg_output
dpkg_output="$(dpkg -l 'linux-image-[0-9]*' | awk '$1=="ii"')" || fatal_error_handler || return
[ "${dpkg_output}" != "" ] || fatal_error_handler || return
local version_to_keep_container
version_to_keep_container=($(awk '{print $3}' <<< "${dpkg_output}")) || fatal_error_handler || return
[ 0 -lt "${#version_to_keep_container[@]}" ] || fatal_error_handler || return
local idx1
for ((idx1=0; idx1<${#version_to_keep_container[@]}-1; ++idx1))
do
local idx2
for ((idx2=idx1+1; idx2<${#version_to_keep_container[@]}; ++idx2))
do
if version_test_gt "${version_to_keep_container[idx1]}" "${version_to_keep_container[idx2]}"
then
local tmp="${version_to_keep_container[idx1]}"
version_to_keep_container[idx1]="${version_to_keep_container[idx2]}"
version_to_keep_container[idx2]="${tmp}"
fi
done
done
version_to_keep_container=($(
{
(
IFS=$'\n'
echo "${version_to_keep_container[*]}"
) | tail -2 || fatal_error_handler || return
get_current_kernel_version "${dpkg_output}" || fatal_error_handler || return
} | sort -u)) || fatal_error_handler || return
((1 <= "${#version_to_keep_container[@]}" && "${#version_to_keep_container[@]}" <= 3)) || fatal_error_handler || return
dpkg_output="$(dpkg -l 'linux-headers-*' 'linux-image-*' | awk '$1=="ii"')" || fatal_error_handler || return
[ "${dpkg_output}" != "" ] || fatal_error_handler || return
for ((idx1=0; idx1<${#version_to_keep_container[@]}; ++idx1))
do
dpkg_output="$(awk '$3!="'${version_to_keep_container[idx1]}'"' <<< "${dpkg_output}")" || fatal_error_handler || return
done
dpkg_output="$(awk '$2!="linux-headers-generic"' <<< "${dpkg_output}")" || fatal_error_handler || return
dpkg_output="$(awk '$2!="linux-image-generic"' <<< "${dpkg_output}")" || fatal_error_handler || return
local package_to_remove_container
if [ "${dpkg_output}" != "" ]
then
package_to_remove_container+=($(awk '{print $2}' <<< "${dpkg_output}")) || fatal_error_handler || return
fi
dpkg_output="$(dpkg -l | awk '$1=="rc"')" || fatal_error_handler || return
if [ "${dpkg_output}" != "" ]
then
package_to_remove_container+=($(awk '{print $2}' <<< "${dpkg_output}")) || fatal_error_handler || return
fi
if [ 0 -lt "${#package_to_remove_container[@]}" ]
then
if [ "${gui_required}" = "true" ]
then
(IFS=$'\n';echo "${package_to_remove_container[*]}") | LANG="${language}" zenity --list --title "${title}" --text "${text}" --column "${column}" &> /dev/null || return 0
else
echo "${text}"
(IFS=$'\n';echo "${package_to_remove_container[*]}")
echo -n "${choice}"
read
[ "${REPLY}" != "y" ] && [ "${REPLY}" != "o" ] && return 0
fi
if [ "${gui_required}" = "true" ]
then
local password
password="$(LANG="${language}" zenity --title "${title}" --password)" || return 0
sudo -S -- apt-get -y purge "${package_to_remove_container[@]}" <<< "${password}" || fatal_error_handler || return
sudo -S -- apt-get -y autoclean <<< "${password}" || fatal_error_handler || return
sudo -S -- apt-get -y clean <<< "${password}" || fatal_error_handler || return
sudo -S -- apt-get -y autoremove <<< "${password}" || fatal_error_handler || return
unset password
else
sudo -- apt-get -y purge "${package_to_remove_container[@]}" || fatal_error_handler || return
sudo -- apt-get -y autoclean || fatal_error_handler || return
sudo -- apt-get -y clean || fatal_error_handler || return
sudo -- apt-get -y autoremove || fatal_error_handler || return
fi
if [ "${gui_required}" = "true" ]
then
LANG="${language}" zenity --title "${title}" --info --text "${text2}" --no-wrap
else
echo "${text2}"
fi
fi
}
if [ "$0" = "${BASH_SOURCE[0]}" ]
then
trap cleanup EXIT
declare -r gui_required="$(is_gui_required)"
if [ "${gui_required}" = "true" ]
then
tmp_container+=("$(mktemp -u)")
declare -r logfile="${tmp_container[${#tmp_container[@]}-1]}"
exec &> "${logfile}"
fi
declare -r language="${LANG}"
if [ "${language:0:5}" = "fr_FR" ]
then
declare -r title="Nettoyeur du système"
declare -r text="Voulez vous supprimer les paquets ci-dessous ?"
declare -r text2="Le système a été nettoyé avec succès."
declare -r column="Nom du paquet"
declare -r choice="Choix (o/n) : "
declare -r text3="Contenu du fichier : \"${logfile}\""
else
declare -r title="System cleaner"
declare -r text="Do you want to remove packages below?"
declare -r text2="System has been successfully cleaned."
declare -r column="Package name"
declare -r choice="Choice (y/n): "
declare -r text3="Content of file: \"${logfile}\""
fi
if [ "${gui_required}" = "true" ]
then
echo "${text3}"
fi
LANG="C"
main "$@" || fatal_error_handler || [ "${gui_required}" = "false" ] || LANG="${language}" zenity --title "${title}" --text-info --filename "${logfile}"
fi