#!/bin/bash do { #//////////////////////////////////// # DietPi # #//////////////////////////////////// # Created by Daniel Knight / daniel.knight@dietpi.com / dietpi.com #//////////////////////////////////// # # Info: # - Cleans "crap" on users system :) # # - Usage # /DietPi/dietpi/dietpi-cleaner no-input = menu # /DietPi/dietpi/dietpi-cleaner 1 = Run Enabled cleaners (no menu). # /DietPi/dietpi/dietpi-cleaner 2 = Run All cleaners (no menu). #//////////////////////////////////// #Grab Input (valid interger) setvar INPUT = '0' if [[ $1 =~ ^-?[0-9]+$ ]] { setvar INPUT = "$1" } #Import DietPi-Globals --------------------------------------------------------------- source /DietPi/dietpi/func/dietpi-globals G_CHECK_ROOT_USER G_CHECK_ROOTFS_RW export G_PROGRAM_NAME='DietPi-Cleaner' #Import DietPi-Globals --------------------------------------------------------------- #///////////////////////////////////////////////////////////////////////////////////// # Globals #///////////////////////////////////////////////////////////////////////////////////// setvar FP_TEMP = ""/tmp/.dietpi-cleaner"" #///////////////////////////////////////////////////////////////////////////////////// # Banners #///////////////////////////////////////////////////////////////////////////////////// proc Banner_Cleaning { echo -e "\n\n" echo -e "\e[38;5;154m───────────────────────────────────────\e[0m\n\e[1mDietPi-Cleaner\e[0m\n - $INFO_CLEAN_NAME\n\e[38;5;154m───────────────────────────────────────\e[0m" } #///////////////////////////////////////////////////////////////////////////////////// # Menu #///////////////////////////////////////////////////////////////////////////////////// #Whippy Whoopy Whiptail! setvar WHIP_BACKTITLE = ''- DietPi-Cleaner -'' setvar WHIP_TITLE = "$WHIP_BACKTITLE" setvar WHIP_QUESTION = '0' setvar CHOICE = '0' setvar TARGETMENUID = '0' proc Menu_Exit { setvar WHIP_TITLE = ''Exit DietPi-Cleaner?'' setvar WHIP_QUESTION = ''Exit DietPi-Cleaner?'' whiptail --title $WHIP_TITLE --yesno $WHIP_QUESTION --backtitle $WHIP_TITLE --yes-button "Ok" --no-button "Back" --defaultno 9 55 setvar CHOICE = ""$? if (( $CHOICE == 0 )) { #exit setvar TARGETMENUID = '-1' } else { #Return to Main Menu setvar TARGETMENUID = '0' } } #TARGETMENUID=0 proc Menu_Main { setvar WHIP_TITLE = "$WHIP_BACKTITLE" #Get current RootFS usage Update_Space_Used setvar TARGETMENUID = '0' setvar WHIP_QUESTION = ""Free up used space and system resources:\n - RootFS usage current = $ROOT_SPACE_USED_CURRENT MB\n - RootFS space cleared = $ROOT_SPACE_FREE_DELTA MB"" setvar OPTION = $(whiptail --title "$WHIP_TITLE" --backtitle "$WHIP_BACKTITLE" --menu "$WHIP_QUESTION" --cancel-button "Exit" 15 75 5 \ "Help" "What does DietPi-Cleaner do?" \ "Cleaners" "Control which cleaners are enabled." \ " - Files" "Set file cleaner options." \ "Test" "Simulate the cleaning process, without modifying any data." \ "Run" "Run enabled cleaners." 3>&1 1>&2 2>&3) setvar CHOICE = ""$? if (( $CHOICE == 0 )) { case (OPTION) { Help { whiptail --title "DietPi-Cleaner Help" --msgbox "DietPi-Cleaner is a program that allows you to remove unwanted junk from your DietPi system, freeing up filesystem space in the process.\n\nSimply enable the cleaners you require, then select Test to see what will happen, without modifying your system.\nOnce your satisfied with the Test results, select Run to clean your system.\n\nMore information:\n - http://dietpi.com/phpbb/viewtopic.php?f=8&t=5&p=623#p623" --backtitle $WHIP_BACKTITLE 16 75 } " - Files" { setvar TARGETMENUID = '2' } Cleaners { setvar TARGETMENUID = '1' } Test { #Enable test setvar DRY_RUN = '1' #check for at least 1 enabled. local at_least_one_cleaner_is_enabled=0 for ((i=0; i<$MAX_CLEANERS; i++)) do if (( ${aEnabledCleaners[$i]} == 1 )); then at_least_one_cleaner_is_enabled=1 break fi done if (( $at_least_one_cleaner_is_enabled == 1 )) { #Yes/No whiptail --title "Run DietPi-Cleaner?" --yesno "DietPi-Cleaner will now simulate your enabled cleaners.\n\n(Notice): No data will be modified.\n\nContinue with test run?" --backtitle $WHIP_BACKTITLE --defaultno 12 70 setvar CHOICE = ""$? if (( $CHOICE == 0 )) { Run_Cleaners } } else { whiptail --title "No cleaner jobs enabled" --msgbox "DietPi-Cleaner could not be run as there are no enabled cleaners. Please go to cleaners, then select which you would like to enable." 10 70 } } Run { #Disable test setvar DRY_RUN = '0' #check for at least 1 enabled. local at_least_one_cleaner_is_enabled=0 for ((i=0; i<$MAX_CLEANERS; i++)) do if (( ${aEnabledCleaners[$i]} == 1 )); then at_least_one_cleaner_is_enabled=1 break fi done if (( $at_least_one_cleaner_is_enabled == 1 )) { #Yes/No whiptail --title "Run DietPi-Cleaner?" --yesno "DietPi-Cleaner will now run your enabled cleaners.\n\n(Notice): If you are unsure what this program will do, I would recommend creating a backup with dietpi-backup before proceeding.\n\nWould you like to continue and start the cleaning process?" --backtitle $WHIP_BACKTITLE --defaultno 13 70 setvar CHOICE = ""$? if (( $CHOICE == 0 )) { Run_Cleaners } } else { whiptail --title "No cleaner jobs enabled" --msgbox "DietPi-Cleaner could not be run as there are no enabled cleaners. Please go to cleaners, then select which you would like to enable." 10 70 } } } } else { Menu_Exit } } #TARGETMENUID=1 proc Menu_Cleaners { #Return to main menu setvar TARGETMENUID = '0' #Get on/off whilptail status local aWhiptailLine=() local OnOff_Status="on" for ((i=0; i<$MAX_CLEANERS; i++)) do #On/Off status OnOff_Status="on" if (( ${aEnabledCleaners[$i]} == 0 )); then OnOff_Status="off" fi #Define options if (( $i == 0 )); then aWhiptailLine+=("$i " "Dev - Uninstalls all dev packages (eg: git, lib123-dev)." "$OnOff_Status") elif (( $i == 1 )); then aWhiptailLine+=("$i " "Manpages - Removes offline documentation." "$OnOff_Status") elif (( $i == 2 )); then aWhiptailLine+=("$i " "Files - Scan and remove files matching user include list." "$OnOff_Status") elif (( $i == 3 )); then aWhiptailLine+=("$i " "Logs - Clears the log file directory (/var/log)." "$OnOff_Status") elif (( $i == 4 )); then aWhiptailLine+=("$i " "Apt - Clears the apt cache and runs a fresh update." "$OnOff_Status") else aWhiptailLine+=("New " "Unknown" "$OnOff_Status") fi done setvar WHIP_TITLE = ''- Options : Cleaner Selection -'' setvar WHIP_QUESTION = ''Please use the spacebar to toggle which cleaners are enabled.'' whiptail --title $WHIP_TITLE --checklist $WHIP_QUESTION --backtitle $WHIP_TITLE --separate-output 14 75 5 ${aWhiptailLine[@]} 2> "$FP_TEMP" setvar CHOICE = ""$? if (( $CHOICE == 0 )) { for ((i=0; i<$MAX_CLEANERS; i++)) do aEnabledCleaners[$i]=0 if (( $(cat "$FP_TEMP" | grep -ci -m1 "$i ") == 1 )); then aEnabledCleaners[$i]=1 fi done } #Clean up temp files rm $FP_TEMP &> /dev/null #Delete[] array unset aWhiptailLine } #TARGETMENUID=2 proc Menu_Options_Files { #Return to main menu setvar TARGETMENUID = '0' local option_1_text="Include mount directory (/mnt/*) during file scan" local include_mnt_status="Disabled" if (( $INCLUDE_MNT == 1 )) { setvar include_mnt_status = ""Enabled"" } local option_2_text="Modify filenames/extensions to include during scan." setvar WHIP_QUESTION = ""Files: Cleaner options.\n(NB) The cleaner named 'Files' must be enabled for this to work."" setvar WHIP_TITLE = ''- Files: Cleaner options -'' setvar OPTION = $(whiptail --title "$WHIP_TITLE" --backtitle "$WHIP_BACKTITLE" --menu "$WHIP_QUESTION" --cancel-button "Exit" 12 68 2 \ "$option_1_text" ": $include_mnt_status" \ "$option_2_text" "" 3>&1 1>&2 2>&3) setvar CHOICE = ""$? if (( $CHOICE == 0 )) { case (OPTION) { "$option_1_text" { if (( $INCLUDE_MNT == 1 )) { setvar INCLUDE_MNT = '0' } else { setvar INCLUDE_MNT = '1' } setvar TARGETMENUID = '2' } "$option_2_text" { nano $FILEPATH_CUSTOMFILES setvar TARGETMENUID = '2' } } } } #///////////////////////////////////////////////////////////////////////////////////// # Cleaner stats #///////////////////////////////////////////////////////////////////////////////////// # Space free after running cleaner setvar ROOT_SPACE_USED_BEFORE = '0' setvar ROOT_SPACE_USED_AFTER = '0' setvar ROOT_SPACE_USED_CURRENT = '0' setvar ROOT_SPACE_FREE_DELTA = ""Cleaner has not been run - 0"" setvar ROOTFS_DEVICE_PATH = $(sed -n 4p /DietPi/dietpi/.hw_model) proc Update_Space_Used { setvar ROOT_SPACE_USED_CURRENT = $(df --block-size MB | grep "$ROOTFS_DEVICE_PATH" | awk '{ print $3 }' | tr -d 'MB') } #///////////////////////////////////////////////////////////////////////////////////// # Cleaner Funcs #///////////////////////////////////////////////////////////////////////////////////// setvar MAX_CLEANERS = '5' setvar aEnabledCleaners = ''() for ((i=0; i<$MAX_CLEANERS; i++)) do aEnabledCleaners[$i]=0 done setvar INCLUDE_MNT = '0' setvar DRY_RUN = '0' setvar INFO_CLEAN_NAME = """" proc Run_Cleaners { #stop services /DietPi/dietpi/dietpi-services stop Update_Space_Used setvar ROOT_SPACE_USED_BEFORE = "$ROOT_SPACE_USED_CURRENT" #Run enabled cleaners for ((i=0; i<$MAX_CLEANERS; i++)) do if (( ${aEnabledCleaners[$i]} == 1 )); then Run_Cleaner_"$i" fi done Update_Space_Used setvar ROOT_SPACE_USED_AFTER = "$ROOT_SPACE_USED_CURRENT" #start services /DietPi/dietpi/dietpi-services start #inform user of space cleared. setvar ROOT_SPACE_FREE_DELTA = $(( $ROOT_SPACE_USED_BEFORE - $ROOT_SPACE_USED_AFTER )) setvar WHIP_QUESTION = ""DietPi-Cleaner has finished cleaning RootFS:\n - $ROOT_SPACE_FREE_DELTA MB of space has been cleared."" if (( $INPUT == 0 )) { whiptail --title "DietPi-Cleaner completed." --msgbox $WHIP_QUESTION 10 70 } elif (( $INPUT == 1 )) { echo -e "\n$WHIP_QUESTION\n" } } # Dev Packages proc Run_Cleaner_0 { setvar INFO_CLEAN_NAME = ""Dev packages"" Banner_Cleaning local string_package_names="" while read line { #Convert lined list into a 1 line string. setvar string_package_names = ""$line "" } < <(dpkg -l | grep '\-dev:' | awk '{ print $2 }' | cut -f1 -d":") #add other dev packages setvar string_package_names = ""build-essential git"" #Purge local Yes_or_Simulate="-y" if (( $DRY_RUN == 1 )) { setvar Yes_or_Simulate = ""-s"" } apt-get purge $string_package_names $Yes_or_Simulate apt-get autoremove --purge $Yes_or_Simulate #Update DietPi .installed if (( $DRY_RUN == 0 )) { sed -i "/BUILDESSENTIAL=/c\BUILDESSENTIAL=0" /DietPi/dietpi/.installed sed -i "/GITCLIENT=/c\GITCLIENT=0" /DietPi/dietpi/.installed } } # Man pages / doc proc Run_Cleaner_1 { setvar INFO_CLEAN_NAME = ""Man pages and docs"" Banner_Cleaning local Yes_or_Simulate="-y" if (( $DRY_RUN == 1 )) { setvar Yes_or_Simulate = ""-s"" } apt-get purge man manpages $Yes_or_Simulate apt-get autoremove --purge $Yes_or_Simulate #Remove files if (( $DRY_RUN == 0 )) { rm -R /usr/share/man rm -R /usr/share/doc rm -R /usr/share/doc-base } } # Files proc Run_Cleaner_2 { setvar INFO_CLEAN_NAME = ""Files"" Banner_Cleaning #generate list of files to include. Remove lines with (#) or (space) or (empty) from list cat $FILEPATH_CUSTOMFILES | sed '/#/d' | sed '/ /d' | sed '/^$/d' > "$FP_TEMP" #Check include file has at least one value/line to process. local line_count=$(cat "$FP_TEMP" | wc -l) if (( $line_count == 0 )) { echo -e "\nNo files to find. Have you setup the Files options and added filename entries to match?\n" } else { #Create array to hold user includes local aCustomFiles=() readarray aCustomFiles < "$FP_TEMP" #Generate the find string local find_string="" echo -e "\nSearching for filenames matching:" for ((i=0; i<${#aCustomFiles[@]}; i++)) do echo -e "- ${aCustomFiles[$i]}" if (( $i == 0 )); then find_string="-name ${aCustomFiles[$i]}" else find_string+=" -or -name ${aCustomFiles[$i]}" fi done echo -e "Please wait...." #Find all matching filenames. find / -type f $find_string > "$FP_TEMP" #Remove /mnt from find list if (( $INCLUDE_MNT == 0 )) { sed -i '/\/mnt/d' $FP_TEMP } setvar line_count = $(cat "$FP_TEMP" | wc -l) if (( $line_count == 0 )) { echo -e "\nNo matching filenames were found.\n" } else { echo -e "\nFound the following matching files:\n" } #Remove files while read line { echo -e "- Filepath: $line" if (( $DRY_RUN == 0 )) { echo -e "Deleted.\n" rm $line } } < "$FP_TEMP" #delete[] unset aCustomFiles } rm $FP_TEMP &> /dev/null } # Logs proc Run_Cleaner_3 { setvar INFO_CLEAN_NAME = ""Log files"" Banner_Cleaning if (( $DRY_RUN == 0 )) { /DietPi/dietpi/dietpi-logclear 1 } } # Apt caches proc Run_Cleaner_4 { setvar INFO_CLEAN_NAME = ""Apt cache and update"" Banner_Cleaning if (( $DRY_RUN == 0 )) { apt-get clean rm /var/lib/apt/lists/* -vf G_AGUP } } #///////////////////////////////////////////////////////////////////////////////////// # Settings File #///////////////////////////////////////////////////////////////////////////////////// #Define Location setvar FILEPATH_SETTINGS = ""/DietPi/dietpi/.dietpi-cleaner"" setvar FILEPATH_CUSTOMFILES = ""/DietPi/dietpi/.dietpi-cleaner_custom_files"" proc Read_Settings_File { if test -f $FILEPATH_SETTINGS { #Get line count local line_count=$(cat "$FILEPATH_SETTINGS" | wc -l) #Load settings for ((i=0; i<$line_count; i++)) do aEnabledCleaners[$i]=$(sed -n $(( $i + 1 ))p $FILEPATH_SETTINGS) done } #Custom filescan options if test ! -f $FILEPATH_CUSTOMFILES { cat <<< """ > "$FILEPATH_CUSTOMFILES" # ------------------------------------------------------------------ # Specify filenames or extentions to match during filescan removals. # # One item per line. # # Examples: # *.tmp # ThisFileWillBeDeleted.mp3 # *AnyFilenameContainingThisTextWillBeDeleted* # # To save and exit: # - Press CTRL+X # - Press Y # - Press Enter # ------------------------------------------------------------------ # Uncomment line below to include temp files during scan. #*.tmp # Uncomment line below to include Windows Thumbnail cache during scan. #Thumbs.db """ > "$FILEPATH_CUSTOMFILES" # ------------------------------------------------------------------ # Specify filenames or extentions to match during filescan removals. # # One item per line. # # Examples: # *.tmp # ThisFileWillBeDeleted.mp3 # *AnyFilenameContainingThisTextWillBeDeleted* # # To save and exit: # - Press CTRL+X # - Press Y # - Press Enter # ------------------------------------------------------------------ # Uncomment line below to include temp files during scan. #*.tmp # Uncomment line below to include Windows Thumbnail cache during scan. #Thumbs.db _EOF_ } } proc Write_Settings_File { #Enabled/Disabled Cleaner Settings rm $FILEPATH_SETTINGS &> /dev/null for ((i=0; i<$MAX_CLEANERS; i++)) do echo -e "${aEnabledCleaners[$i]}" >> $FILEPATH_SETTINGS done } #///////////////////////////////////////////////////////////////////////////////////// #Main #///////////////////////////////////////////////////////////////////////////////////// Read_Settings_File #----------------------------------------------------------------------------------- #Run Menu if (( $INPUT == 0 )) { { clear if (( $TARGETMENUID == 0 )) { Menu_Main } elif (( $TARGETMENUID == 1 )) { Menu_Cleaners } elif (( $TARGETMENUID == 2 )) { Menu_Options_Files } } Write_Settings_File #----------------------------------------------------------------------------------- #Run Enabled cleaners (no menu) } elif (( $INPUT == 1 )) { Run_Cleaners #----------------------------------------------------------------------------------- #Run ALL cleaners (no menu) } elif (( $INPUT == 2 )) { for ((i=0; i<$MAX_CLEANERS; i++)) do aEnabledCleaners[$i]=1 done Run_Cleaners } #----------------------------------------------------------------------------------- #delete[] unset aEnabledCleaners #----------------------------------------------------------------------------------- exit #----------------------------------------------------------------------------------- }