#!/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) setglobal INPUT = '0' if [[ $1 =~ ^-?[0-9]+$ ]] { setglobal 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 #///////////////////////////////////////////////////////////////////////////////////// setglobal 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! setglobal WHIP_BACKTITLE = ''- DietPi-Cleaner -'' setglobal WHIP_TITLE = $WHIP_BACKTITLE setglobal WHIP_QUESTION = '0' setglobal CHOICE = '0' setglobal TARGETMENUID = '0' proc Menu_Exit{ setglobal WHIP_TITLE = ''Exit DietPi-Cleaner?'' setglobal WHIP_QUESTION = ''Exit DietPi-Cleaner?'' whiptail --title $WHIP_TITLE --yesno $WHIP_QUESTION --backtitle $WHIP_TITLE --yes-button "Ok" --no-button "Back" --defaultno 9 55 setglobal CHOICE = $Status if sh-expr ' $CHOICE == 0 ' { #exit setglobal TARGETMENUID = '-1' } else { #Return to Main Menu setglobal TARGETMENUID = '0' } } #TARGETMENUID=0 proc Menu_Main{ setglobal WHIP_TITLE = $WHIP_BACKTITLE #Get current RootFS usage Update_Space_Used setglobal TARGETMENUID = '0' setglobal 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"" setglobal 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] setglobal CHOICE = $Status if sh-expr ' $CHOICE == 0 ' { match $OPTION { with 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 with " - Files" setglobal TARGETMENUID = '2' with Cleaners setglobal TARGETMENUID = '1' with Test #Enable test setglobal 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 sh-expr ' $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 setglobal CHOICE = $Status if sh-expr ' $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 } with Run #Disable test setglobal 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 sh-expr ' $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 setglobal CHOICE = $Status if sh-expr ' $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 setglobal 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 setglobal WHIP_TITLE = ''- Options : Cleaner Selection -'' setglobal 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 setglobal CHOICE = $Status if sh-expr ' $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 setglobal TARGETMENUID = '0' local option_1_text="Include mount directory (/mnt/*) during file scan" local include_mnt_status="Disabled" if sh-expr ' $INCLUDE_MNT == 1 ' { setglobal include_mnt_status = '"Enabled'" } local option_2_text="Modify filenames/extensions to include during scan." setglobal WHIP_QUESTION = '"Files: Cleaner options.\n(NB) The cleaner named 'Files' must be enabled for this to work.'" setglobal WHIP_TITLE = ''- Files: Cleaner options -'' setglobal 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] setglobal CHOICE = $Status if sh-expr ' $CHOICE == 0 ' { match $OPTION { with "$option_1_text" if sh-expr ' $INCLUDE_MNT == 1 ' { setglobal INCLUDE_MNT = '0' } else { setglobal INCLUDE_MNT = '1' } setglobal TARGETMENUID = '2' with "$option_2_text" nano $FILEPATH_CUSTOMFILES setglobal TARGETMENUID = '2' } } } #///////////////////////////////////////////////////////////////////////////////////// # Cleaner stats #///////////////////////////////////////////////////////////////////////////////////// # Space free after running cleaner setglobal ROOT_SPACE_USED_BEFORE = '0' setglobal ROOT_SPACE_USED_AFTER = '0' setglobal ROOT_SPACE_USED_CURRENT = '0' setglobal ROOT_SPACE_FREE_DELTA = '"Cleaner has not been run - 0'" setglobal ROOTFS_DEVICE_PATH = $[sed -n 4p /DietPi/dietpi/.hw_model] proc Update_Space_Used{ setglobal ROOT_SPACE_USED_CURRENT = $[df --block-size MB | grep $ROOTFS_DEVICE_PATH | awk '{ print $3 }' | tr -d 'MB] } #///////////////////////////////////////////////////////////////////////////////////// # Cleaner Funcs #///////////////////////////////////////////////////////////////////////////////////// setglobal MAX_CLEANERS = '5' setglobal aEnabledCleaners = ''() for ((i=0; i<$MAX_CLEANERS; i++)) do aEnabledCleaners[$i]=0 done setglobal INCLUDE_MNT = '0' setglobal DRY_RUN = '0' setglobal INFO_CLEAN_NAME = ''"" proc Run_Cleaners{ #stop services /DietPi/dietpi/dietpi-services stop Update_Space_Used setglobal 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 setglobal ROOT_SPACE_USED_AFTER = $ROOT_SPACE_USED_CURRENT #start services /DietPi/dietpi/dietpi-services start #inform user of space cleared. setglobal ROOT_SPACE_FREE_DELTA = $shExpr(' $ROOT_SPACE_USED_BEFORE - $ROOT_SPACE_USED_AFTER ') setglobal WHIP_QUESTION = ""DietPi-Cleaner has finished cleaning RootFS:\n - $ROOT_SPACE_FREE_DELTA MB of space has been cleared."" if sh-expr ' $INPUT == 0 ' { whiptail --title "DietPi-Cleaner completed." --msgbox $WHIP_QUESTION 10 70 } elif sh-expr ' $INPUT == 1 ' { echo -e "\n$WHIP_QUESTION\n" } } # Dev Packages proc Run_Cleaner_0{ setglobal INFO_CLEAN_NAME = '"Dev packages'" Banner_Cleaning local string_package_names="" while read line { #Convert lined list into a 1 line string. setglobal string_package_names = ""$line "" } < <(dpkg -l | grep '\-dev:' | awk '{ print $2 }' | cut -f1 -d":") #add other dev packages setglobal string_package_names = '"build-essential git'" #Purge local Yes_or_Simulate="-y" if sh-expr ' $DRY_RUN == 1 ' { setglobal Yes_or_Simulate = '"-s'" } apt-get purge $string_package_names $Yes_or_Simulate apt-get autoremove --purge $Yes_or_Simulate #Update DietPi .installed if sh-expr ' $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{ setglobal INFO_CLEAN_NAME = '"Man pages and docs'" Banner_Cleaning local Yes_or_Simulate="-y" if sh-expr ' $DRY_RUN == 1 ' { setglobal Yes_or_Simulate = '"-s'" } apt-get purge man manpages $Yes_or_Simulate apt-get autoremove --purge $Yes_or_Simulate #Remove files if sh-expr ' $DRY_RUN == 0 ' { rm -R /usr/share/man rm -R /usr/share/doc rm -R /usr/share/doc-base } } # Files proc Run_Cleaner_2{ setglobal 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 sh-expr ' $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 sh-expr ' $INCLUDE_MNT == 0 ' { sed -i '/\/mnt/d' $FP_TEMP } setglobal line_count = $[cat $FP_TEMP | wc -l] if sh-expr ' $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 sh-expr ' $DRY_RUN == 0 ' { echo -e "Deleted.\n" rm $line } } < "$FP_TEMP" #delete[] unset aCustomFiles } rm $FP_TEMP &> /dev/null } # Logs proc Run_Cleaner_3{ setglobal INFO_CLEAN_NAME = '"Log files'" Banner_Cleaning if sh-expr ' $DRY_RUN == 0 ' { /DietPi/dietpi/dietpi-logclear 1 } } # Apt caches proc Run_Cleaner_4{ setglobal INFO_CLEAN_NAME = '"Apt cache and update'" Banner_Cleaning if sh-expr ' $DRY_RUN == 0 ' { apt-get clean rm /var/lib/apt/lists/* -vf G_AGUP } } #///////////////////////////////////////////////////////////////////////////////////// # Settings File #///////////////////////////////////////////////////////////////////////////////////// #Define Location setglobal FILEPATH_SETTINGS = '"/DietPi/dietpi/.dietpi-cleaner'" setglobal 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 sh-expr ' $INPUT == 0 ' { #Start DietPi Menu while sh-expr ' $TARGETMENUID > -1 ' { clear if sh-expr ' $TARGETMENUID == 0 ' { Menu_Main } elif sh-expr ' $TARGETMENUID == 1 ' { Menu_Cleaners } elif sh-expr ' $TARGETMENUID == 2 ' { Menu_Options_Files } } Write_Settings_File #----------------------------------------------------------------------------------- #Run Enabled cleaners (no menu) } elif sh-expr ' $INPUT == 1 ' { Run_Cleaners #----------------------------------------------------------------------------------- #Run ALL cleaners (no menu) } elif sh-expr ' $INPUT == 2 ' { for ((i=0; i<$MAX_CLEANERS; i++)) do aEnabledCleaners[$i]=1 done Run_Cleaners } #----------------------------------------------------------------------------------- #delete[] unset aEnabledCleaners #----------------------------------------------------------------------------------- exit #----------------------------------------------------------------------------------- }