Skip to content

Instantly share code, notes, and snippets.

@eboye
Created September 16, 2025 18:23
Show Gist options
  • Select an option

  • Save eboye/9f6b3140b130cda1fb9ce7b1596c1490 to your computer and use it in GitHub Desktop.

Select an option

Save eboye/9f6b3140b130cda1fb9ce7b1596c1490 to your computer and use it in GitHub Desktop.
Ubuntu Cleanup Script
#!/bin/bash
# Check or install dialog
if ! command -v dialog &>/dev/null; then
echo "'dialog' is not installed."
read -p "Install now for better progress display? (y/n): " resp
if [[ $resp =~ ^[Yy]$ ]]; then
echo "Installing dialog..."
sudo apt-get update &>/dev/null
sudo apt-get install -y dialog &>/dev/null
if ! command -v dialog &>/dev/null; then
echo "Installation failed. Proceeding without dialog."
DIALOG=false
else
DIALOG=true
fi
else
DIALOG=false
fi
else
DIALOG=true
fi
# Options array: index, description, default state
OPTIONS=(
1 "Clean APT cache" off
2 "Remove old log files" off
3 "Clear thumbnail cache" off
4 "Remove unused kernels" off
5 "Remove orphaned packages" off
6 "Remove temporary files" off
7 "Clean Docker images/containers" off
8 "Remove unused Snap packages" off
)
# Calculate total selected tasks
total_tasks=0
declare -a selected_choices
# When choosing options, store selected choices for progress reporting
get_choices() {
if [ "$DIALOG" = true ]; then
choices=$(dialog --checklist "Select cleanup options:" 15 70 8 \
"${OPTIONS[@]}" --stdout)
[ $? -ne 0 ] && { echo "Canceled"; exit 1; }
else
# fallback to sequential prompts
selected_choices=()
local count=0
for i in {1..8}; do
name="${OPTIONS[$(( (i-1)*3+1 ))]}"
read -p "$name? (y/n): " resp
if [[ $resp =~ ^[Yy]$ ]]; then
selected_choices+=("$i")
total_tasks=$((total_tasks+1))
fi
done
return
fi
# remove quotes
for c in $choices; do
selected_choices+=("$(echo "$c" | tr -d '"')")
done
total_tasks=${#selected_choices[@]}
}
# Run progress updates with message
progress_update() {
local percent=$1
local msg=$2
local info="$3"
if [ "$DIALOG" = true ]; then
echo "$percent" | dialog --title "$msg" --gauge "$msg" -1 70 "$percent" --yesno "$info" 6 50
# We cannot directly embed info line below gauge, capture and display after
else
echo -ne "\r[$percent%] $msg | $info"
fi
}
# Run each selected task with progress and info update
execute_option() {
local choice="$1"
local count=$2
local info="$count of $total_tasks completed"
case "$choice" in
1)
local msg="Cleaning APT cache..."
if [ "$DIALOG" = true ]; then
echo "0" | dialog --title "$msg" --gauge "$msg" 10 70 0
echo "$((count*100/total_tasks))" | dialog --title "$msg" --gauge "$msg" 10 70 "$((count*100/total_tasks))"
sudo apt clean &>/dev/null
sudo apt autoremove -y &>/dev/null
sudo apt-get clean &>/dev/null
sudo apt-get autoremove -y &>/dev/null
else
echo "$msg"
echo -e "$info"
sudo apt clean &>/dev/null
sudo apt autoremove -y &>/dev/null
sudo apt-get clean &>/dev/null
sudo apt-get autoremove -y &>/dev/null
fi
;;
2)
local msg="Removing old log files..."
if [ "$DIALOG" = true ]; then
echo "0" | dialog --title "$msg" --gauge "$msg" 10 70 0
echo "$((count*100/total_tasks))" | dialog --title "$msg" --gauge "$msg" 10 70 "$((count*100/total_tasks))"
sudo find /var/log -type f -name '*gz' -delete &>/dev/null
else
echo "$msg"
echo -e "$info"
sudo find /var/log -type f -name '*gz' -delete &>/dev/null
fi
;;
3)
local msg="Clearing thumbnail cache..."
if [ "$DIALOG" = true ]; then
echo "0" | dialog --title "$msg" --gauge "$msg" 10 70 0
echo "$((count*100/total_tasks))" | dialog --title "$msg" --gauge "$msg" 10 70 "$((count*100/total_tasks))"
rm -rf ~/.cache/thumbnails/* &>/dev/null
else
echo "$msg"
echo -e "$info"
rm -rf ~/.cache/thumbnails/* &>/dev/null
fi
;;
4)
local msg="Removing old kernels..."
if [ "$DIALOG" = true ]; then
echo "0" | dialog --title "$msg" --gauge "$msg" 10 70 0
echo "$((count*100/total_tasks))" | dialog --title "$msg" --gauge "$msg" 10 70 "$((count*100/total_tasks))"
sudo apt-get purge -y $(dpkg --list 'linux-image*' | grep '^ii' | awk '{ if ($2 != "linux-image-$(uname -r)") print $2 }') &>/dev/null
sudo update-grub &>/dev/null
else
echo "$msg"
echo -e "$info"
sudo apt-get purge -y $(dpkg --list 'linux-image*' | grep '^ii' | awk '{ if ($2 != "linux-image-$(uname -r)") print $2 }') &>/dev/null
sudo update-grub &>/dev/null
fi
;;
5)
local msg="Removing orphaned packages..."
if [ "$DIALOG" = true ]; then
echo "0" | dialog --title "$msg" --gauge "$msg" 10 70 0
echo "$((count*100/total_tasks))" | dialog --title "$msg" --gauge "$msg" 10 70 "$((count*100/total_tasks))"
sudo apt autoremove --purge -y &>/dev/null
else
echo "$msg"
echo -e "$info"
sudo apt autoremove --purge -y &>/dev/null
fi
;;
6)
local msg="Removing temp files..."
if [ "$DIALOG" = true ]; then
echo "0" | dialog --title "$msg" --gauge "$msg" 10 70 0
echo "$((count*100/total_tasks))" | dialog --title "$msg" --gauge "$msg" 10 70 "$((count*100/total_tasks))"
sudo rm -rf /tmp/* ~/.cache/* &>/dev/null
else
echo "$msg"
echo -e "$info"
sudo rm -rf /tmp/* ~/.cache/* &>/dev/null
fi
;;
7)
local msg="Cleaning Docker..."
if command -v docker &>/dev/null; then
if [ "$DIALOG" = true ]; then
echo "0" | dialog --title "$msg" --gauge "$msg" 10 70 0
echo "$((count*100/total_tasks))" | dialog --title "$msg" --gauge "$msg" 10 70 "$((count*100/total_tasks))"
docker system prune -af &>/dev/null
else
echo "$msg"
echo -e "$info"
docker system prune -af &>/dev/null
fi
fi
;;
8)
local msg="Removing unused Snap packages..."
if [ "$DIALOG" = true ]; then
echo "0" | dialog --title "$msg" --gauge "$msg" 10 70 0
echo "$((count*100/total_tasks))" | dialog --title "$msg" --gauge "$msg" 10 70 "$((count*100/total_tasks))"
sudo snap list --all | awk '/disabled/{print $1, $3}' | while read -r snapname revision; do
sudo snap remove "$snapname" --revision="$revision" &>/dev/null
done
else
echo "$msg"
echo -e "$info"
sudo snap list --all | awk '/disabled/{print $1, $3}' | while read -r snapname revision; do
sudo snap remove "$snapname" --revision="$revision" &>/dev/null
done
fi
;;
esac
}
# Main
if [ "$DIALOG" = true ]; then
# Show initial gauge
echo "0" | dialog --title "Preparing" --gauge "Initializing..." 10 70 0
get_choices
# Run each selected with progress update
for i in "${!selected_choices[@]}"; do
choice="${selected_choices[i]}"
finished_count=$((i+1))
progress_update=$((finished_count*100/total_tasks))
info_text="$finished_count of $total_tasks completed"
execute_option "$choice" "$finished_count"
done
dialog --msgbox "Cleanup complete." 6 40
else
# fallback
get_choices
local count=0
for choice in "${selected_choices[@]}"; do
((count++))
info="$count of ${#selected_choices[@]} completed"
execute_option "$choice" "$count"
done
echo "Cleanup completed."
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment