Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/bin/bash
- # Exit immediately if a command exits with a non-zero status
- set -e
- set -o pipefail
- # Define backup directory
- BACKUP_DIR="$HOME/.systemd_unit_backup"
- # Ensure the backup directory exists
- mkdir -p "$BACKUP_DIR"
- # Declare associative array for Desktop Environments and their corresponding packages
- declare -A DESKTOP_ENVS=(
- [GNOME]="gnome-shell"
- [KDE]="kde-plasma-desktop"
- [XFCE]="xfce4"
- [LXDE]="lxde"
- [MATE]="mate-desktop-environment"
- [Cinnamon]="cinnamon"
- [Budgie]="budgie-desktop"
- [Deepin]="deepin-desktop-environment"
- [LXQt]="lxqt"
- )
- # Log file for script operations
- LOG_FILE="$BACKUP_DIR/system_maintenance_$(date +%F_%T).log"
- # Function to log messages
- log() {
- echo "$(date '+%Y-%m-%d %H:%M:%S') : $*" | tee -a "$LOG_FILE"
- }
- # Function to handle errors
- handle_error() {
- local exit_code=$?
- local message="$1"
- if [ "$exit_code" -ne 0 ]; then
- whiptail --title "Error" --msgbox "$message" 8 78
- log "ERROR: $message"
- fi
- return "$exit_code"
- }
- # Function to ask for sudo privileges
- ask_for_sudo() {
- if ! sudo -v; then
- whiptail --title "Sudo Access Required" --msgbox "Sudo access is required to proceed. Please ensure you have sufficient permissions." 8 78
- exit 1
- else
- # Keep-alive: update existing sudo timestamp until script finishes
- sudo -v
- while true; do
- sleep 60
- sudo -n true
- kill -0 "$$" || exit
- done 2>/dev/null &
- fi
- }
- # Generic function to display menus
- display_menu() {
- local title="$1"
- local prompt="$2"
- shift 2
- local options=("$@")
- whiptail --title "$title" --menu "$prompt" 25 78 15 "${options[@]}" 3>&2 2>&1 1>&3
- }
- # Function for confirmation prompts
- confirm_action() {
- local title="$1"
- local message="$2"
- whiptail --title "$title" --yesno "$message" 10 60
- }
- # Function to display the main menu
- main_menu() {
- local choice
- choice=$(display_menu "System Maintenance Menu" "Choose a category:" \
- "1" "System Updates & Drivers" \
- "2" "Desktop Environment & Display" \
- "3" "Boot & Disk Management" \
- "4" "Network & Security" \
- "5" "System Tools & Utilities" \
- "6" "Backup & Restore" \
- "7" "Exit")
- case $choice in
- 1) system_updates_drivers_menu ;;
- 2) desktop_environment_display_menu ;;
- 3) boot_disk_management_menu ;;
- 4) network_security_menu ;;
- 5) system_tools_utilities_menu ;;
- 6) backup_restore_menu ;;
- 7) exit 0 ;;
- *) log "Invalid selection: $choice"; main_menu ;;
- esac
- }
- # Function for Backup & Restore menu
- backup_restore_menu() {
- local choice
- choice=$(display_menu "Backup & Restore" "Choose an action:" \
- "1" "Backup System" \
- "2" "Restore System from Backup" \
- "3" "Back to Main Menu")
- case $choice in
- 1) backup_system ;;
- 2) restore_system_from_backup ;;
- 3) main_menu ;;
- *) log "Invalid selection: $choice"; backup_restore_menu ;;
- esac
- }
- # Function to backup the system
- backup_system() {
- # Prompt the user to select a backup destination
- local backup_folder
- backup_folder=$(whiptail --title "Select Backup Folder" --inputbox "Enter the path to an empty folder for backup:" 10 60 "$HOME/backup" 3>&1 1>&2 2>&3)
- if [ $? -ne 0 ]; then
- log "Backup cancelled by the user."
- return
- fi
- if [ -z "$backup_folder" ]; then
- whiptail --title "Error" --msgbox "No backup folder specified." 8 78
- log "Backup failed: No backup folder specified."
- return
- fi
- # Check if the folder exists; if not, create it
- if [ ! -d "$backup_folder" ]; then
- mkdir -p "$backup_folder" || handle_error "Failed to create backup directory."
- fi
- # Ensure the folder is empty
- if [ "$(ls -A "$backup_folder")" ]; then
- whiptail --title "Error" --msgbox "The selected folder is not empty. Please choose an empty folder." 8 78
- log "Backup failed: Backup folder is not empty."
- return
- fi
- # Start the backup process with a progress gauge
- whiptail --title "Backing Up System" --gauge "Starting system backup..." 10 60 0
- # Perform the backup using rsync with progress
- rsync -aAXv --exclude={"/dev/*","/proc/*","/sys/*","/tmp/*","/run/*","/mnt/*","/media/*","/lost+found"} / "$backup_folder" &>> "$LOG_FILE" &
- local pid=$!
- local delay=0
- local progress=0
- while kill -0 "$pid" 2>/dev/null; do
- sleep 1
- delay=$((delay + 1))
- progress=$(( progress + 5 ))
- if [ "$progress" -ge 100 ]; then
- progress=99
- fi
- whiptail --title "Backing Up System" --gauge "Backing up system..." 10 60 "$progress"
- done
- wait "$pid"
- local exit_code=$?
- if [ "$exit_code" -eq 0 ]; then
- whiptail --title "Backup Complete" --msgbox "System backup completed successfully to $backup_folder." 8 78
- log "System backup completed successfully to $backup_folder."
- else
- handle_error "System backup failed. Check the log file at $LOG_FILE for details."
- fi
- }
- # Function to restore the system from a backup
- restore_system_from_backup() {
- # Prompt the user to select a backup directory
- local backup_folder
- backup_folder=$(whiptail --title "Select Backup Folder" --inputbox "Enter the path to the backup folder:" 10 60 "$HOME/backup" 3>&1 1>&2 2>&3)
- if [ $? -ne 0 ]; then
- log "Restore cancelled by the user."
- return
- fi
- if [ -z "$backup_folder" ] || [ ! -d "$backup_folder" ]; then
- whiptail --title "Error" --msgbox "Invalid backup folder specified." 8 78
- log "Restore failed: Invalid backup folder."
- return
- fi
- # Confirm restoration as it will overwrite system files
- if ! confirm_action "Confirm Restore" "Are you sure you want to restore the system from $backup_folder? This will overwrite current system files."; then
- log "Restore cancelled by the user."
- return
- fi
- # Start the restoration process with a progress gauge
- whiptail --title "Restoring System" --gauge "Starting system restoration..." 10 60 0
- # Perform the restoration using rsync with progress
- rsync -aAXv --exclude={"/dev/*","/proc/*","/sys/*","/tmp/*","/run/*","/mnt/*","/media/*","/lost+found"} "$backup_folder"/ / &>> "$LOG_FILE" &
- local pid=$!
- local delay=0
- local progress=0
- while kill -0 "$pid" 2>/dev/null; do
- sleep 1
- delay=$((delay + 1))
- progress=$(( progress + 5 ))
- if [ "$progress" -ge 100 ]; then
- progress=99
- fi
- whiptail --title "Restoring System" --gauge "Restoring system..." 10 60 "$progress"
- done
- wait "$pid"
- local exit_code=$?
- if [ "$exit_code" -eq 0 ]; then
- whiptail --title "Restore Complete" --msgbox "System restored successfully from $backup_folder." 8 78
- log "System restored successfully from $backup_folder."
- else
- handle_error "System restore failed. Check the log file at $LOG_FILE for details."
- fi
- }
- # Function for System Updates & Drivers menu
- system_updates_drivers_menu() {
- local choice
- choice=$(display_menu "System Updates & Drivers" "Choose an action:" \
- "1" "Update and Upgrade System" \
- "2" "Install Missing Drivers" \
- "3" "Remove NVIDIA Drivers" \
- "4" "Fix Package Dependencies" \
- "5" "Remove Unused Packages" \
- "6" "Install NVIDIA Drivers" \
- "7" "Flatpak Repair" \
- "8" "Back to Main Menu")
- case $choice in
- 1) update_system ;;
- 2) install_missing_drivers ;;
- 3) remove_nvidia_drivers ;;
- 4) fix_package_dependencies ;;
- 5) remove_unused_packages ;;
- 6) install_nvidia ;;
- 7) flatpak_repair ;;
- 8) main_menu ;;
- *) log "Invalid selection: $choice"; system_updates_drivers_menu ;;
- esac
- }
- # Function to update and upgrade the system
- update_system() {
- whiptail --title "System Update" --infobox "Updating package lists..." 8 78
- sudo apt-get update &>> "$LOG_FILE" || handle_error "Failed to update package lists."
- whiptail --title "System Upgrade" --infobox "Upgrading installed packages..." 8 78
- sudo apt-get upgrade -y &>> "$LOG_FILE" || handle_error "Failed to upgrade packages."
- whiptail --title "System Update" --msgbox "System successfully updated and upgraded." 8 78
- log "System successfully updated and upgraded."
- }
- # Function to install missing drivers
- install_missing_drivers() {
- whiptail --title "Install Missing Drivers" --infobox "Identifying and installing missing drivers..." 8 78
- sudo ubuntu-drivers autoinstall &>> "$LOG_FILE" || handle_error "Failed to install missing drivers."
- whiptail --title "Install Missing Drivers" --msgbox "Missing drivers have been installed successfully." 8 78
- log "Missing drivers installed successfully."
- }
- # Function to remove NVIDIA drivers
- remove_nvidia_drivers() {
- if ! confirm_action "Remove NVIDIA Drivers" "Are you sure you want to remove all NVIDIA drivers and related packages?"; then
- log "NVIDIA driver removal cancelled by the user."
- return
- fi
- whiptail --title "Removing NVIDIA Drivers" --infobox "Removing NVIDIA drivers and related packages..." 8 78
- sudo apt-get purge '^nvidia-.*' -y &>> "$LOG_FILE" || handle_error "Failed to purge NVIDIA packages."
- sudo apt-get autoremove -y &>> "$LOG_FILE" || handle_error "Failed to autoremove NVIDIA dependencies."
- # Remove NVIDIA related directories and files
- sudo rm -rf /usr/local/cuda* /usr/local/nvidia* /etc/OpenCL/vendors/nvidia.icd &>> "$LOG_FILE" || handle_error "Failed to remove NVIDIA directories."
- sudo rm -rf /etc/X11/xorg.conf.d/10-nvidia.conf /etc/modprobe.d/nvidia-installer-disable-nouveau.conf &>> "$LOG_FILE" || handle_error "Failed to remove NVIDIA configuration files."
- sudo rm -rf /var/log/nvidia* /var/lib/nvidia* &>> "$LOG_FILE" || handle_error "Failed to remove NVIDIA log and lib files."
- whiptail --title "Remove NVIDIA Drivers" --msgbox "NVIDIA drivers and related files have been removed successfully." 8 78
- log "NVIDIA drivers and related files removed successfully."
- }
- # Function to fix package dependencies
- fix_package_dependencies() {
- if ! confirm_action "Fix Package Dependencies" "Attempt to fix any broken package dependencies?"; then
- log "Fix package dependencies cancelled by the user."
- return
- fi
- whiptail --title "Fixing Package Dependencies" --infobox "Attempting to fix package dependencies..." 8 78
- sudo apt-get update &>> "$LOG_FILE" || handle_error "Failed to update package lists."
- sudo apt-get -f install -y &>> "$LOG_FILE" || handle_error "Failed to fix package dependencies."
- whiptail --title "Fix Package Dependencies" --msgbox "Package dependencies fixed successfully." 8 78
- log "Package dependencies fixed successfully."
- }
- # Function to remove unused packages
- remove_unused_packages() {
- if ! confirm_action "Remove Unused Packages" "Remove packages that are no longer needed?"; then
- log "Remove unused packages cancelled by the user."
- return
- fi
- whiptail --title "Removing Unused Packages" --infobox "Removing unused packages..." 8 78
- sudo apt-get autoremove -y &>> "$LOG_FILE" || handle_error "Failed to remove unused packages."
- whiptail --title "Remove Unused Packages" --msgbox "Unused packages removed successfully." 8 78
- log "Unused packages removed successfully."
- }
- # Function to install NVIDIA drivers
- install_nvidia() {
- whiptail --title "Installing NVIDIA Drivers" --infobox "Updating system packages..." 8 78
- sudo apt-get update && sudo apt-get upgrade -y &>> "$LOG_FILE" || handle_error "Failed to update and upgrade system."
- whiptail --title "Installing NVIDIA Drivers" --infobox "Installing necessary software properties..." 8 78
- sudo apt-get install software-properties-common -y &>> "$LOG_FILE" || handle_error "Failed to install software-properties-common."
- whiptail --title "Installing NVIDIA Drivers" --infobox "Adding the graphics drivers PPA..." 8 78
- sudo add-apt-repository ppa:graphics-drivers/ppa -y &>> "$LOG_FILE" || handle_error "Failed to add graphics drivers PPA."
- sudo apt-get update &>> "$LOG_FILE" || handle_error "Failed to update package lists after adding PPA."
- whiptail --title "Installing NVIDIA Drivers" --infobox "Identifying the recommended NVIDIA driver..." 8 78
- local recommended_driver
- recommended_driver=$(ubuntu-drivers devices | grep "recommended" | awk '{print $3}')
- if [[ -z "$recommended_driver" ]]; then
- whiptail --title "NVIDIA Driver Installation" --msgbox "No recommended NVIDIA driver found. Please check your system and try again." 8 78
- log "No recommended NVIDIA driver found."
- return
- fi
- whiptail --title "Installing NVIDIA Drivers" --infobox "Installing the recommended NVIDIA driver ($recommended_driver)..." 8 78
- sudo apt-get install "$recommended_driver" nvidia-settings -y &>> "$LOG_FILE" || handle_error "Failed to install NVIDIA driver."
- # Backup existing Xorg configuration if it exists
- if [[ -f "/etc/X11/xorg.conf" ]]; then
- sudo cp /etc/X11/xorg.conf "$BACKUP_DIR/xorg.conf.bak_$(date +%F_%T)" &>> "$LOG_FILE" || handle_error "Failed to backup existing Xorg configuration."
- fi
- whiptail --title "Installing NVIDIA Drivers" --infobox "Configuring NVIDIA settings..." 8 78
- sudo nvidia-xconfig &>> "$LOG_FILE" || handle_error "Failed to configure NVIDIA Xorg settings."
- # Ensure LightDM is installed and enabled
- if ! dpkg -s lightdm &>/dev/null; then
- whiptail --title "Installing LightDM" --infobox "Installing LightDM display manager..." 8 78
- sudo apt-get install lightdm -y &>> "$LOG_FILE" || handle_error "Failed to install LightDM."
- fi
- sudo systemctl enable lightdm &>> "$LOG_FILE" || handle_error "Failed to enable LightDM."
- sudo systemctl restart lightdm &>> "$LOG_FILE" || handle_error "Failed to restart LightDM."
- whiptail --title "NVIDIA Driver Installation" --msgbox "NVIDIA drivers, configuration tools, and LightDM have been installed and configured successfully." 8 78
- log "NVIDIA drivers installed and configured successfully."
- }
- # Function to repair Flatpak packages
- flatpak_repair() {
- whiptail --title "Flatpak Repair" --infobox "Repairing Flatpak packages..." 8 78
- sudo flatpak repair &>> "$LOG_FILE" || handle_error "Failed to repair Flatpak packages."
- whiptail --title "Flatpak Update" --infobox "Updating Flatpak packages..." 8 78
- sudo flatpak update -y &>> "$LOG_FILE" || handle_error "Failed to update Flatpak packages."
- whiptail --title "Flatpak Repair" --msgbox "Flatpak repair and update completed successfully." 8 78
- log "Flatpak repair and update completed successfully."
- }
- # Function for Desktop Environment & Display menu
- desktop_environment_display_menu() {
- local choice
- choice=$(display_menu "Desktop Environment & Display" "Choose an action:" \
- "1" "Purge Xorg" \
- "2" "Reset X11" \
- "3" "LightDM Reset" \
- "4" "Make Wayland Default" \
- "5" "Desktop Environment Installer/Remover" \
- "6" "Startx Attempt" \
- "7" "Cinnamon Repair" \
- "8" "Back to Main Menu")
- case $choice in
- 1) purge_xorg ;;
- 2) reset_x11 ;;
- 3) lightdm_reset ;;
- 4) make_wayland_default ;;
- 5) desktop_environment_installer_remover ;;
- 6) startx_attempt ;;
- 7) cinnamon_repair ;;
- 8) main_menu ;;
- *) log "Invalid selection: $choice"; desktop_environment_display_menu ;;
- esac
- }
- # Function to purge Xorg packages
- purge_xorg() {
- if ! confirm_action "Purge Xorg" "Are you sure you want to purge all Xorg packages? This may affect your graphical interface."; then
- log "Purge Xorg cancelled by the user."
- return
- fi
- whiptail --title "Purging Xorg" --infobox "Purging Xorg packages..." 8 78
- sudo apt-get purge '^xorg-.*' -y &>> "$LOG_FILE" || handle_error "Failed to purge Xorg packages."
- sudo apt-get autoremove -y &>> "$LOG_FILE" || handle_error "Failed to autoremove dependencies after purging Xorg."
- whiptail --title "Purge Xorg" --msgbox "Xorg packages have been purged successfully." 8 78
- log "Xorg packages purged successfully."
- }
- # Function to reset X11 configuration
- reset_x11() {
- if ! confirm_action "Reset X11" "This will attempt to reset X11 configuration to distribution defaults and may affect display settings. Continue?"; then
- log "Reset X11 cancelled by the user."
- return
- fi
- whiptail --title "Reset X11" --infobox "Reconfiguring Xserver..." 8 78
- sudo dpkg-reconfigure xserver-xorg &>> "$LOG_FILE" || handle_error "Failed to reconfigure Xserver."
- # Remove user-specific X11 settings
- local x11_conf_files=("$HOME/.config/monitors.xml" "$HOME/.Xauthority" "$HOME/.xinitrc")
- for conf_file in "${x11_conf_files[@]}"; do
- if [[ -f "$conf_file" ]]; then
- rm -f "$conf_file" || handle_error "Failed to remove $conf_file."
- log "Removed user-specific X11 configuration: $conf_file."
- fi
- done
- # Reconfigure display manager if LightDM is active
- if systemctl is-active --quiet lightdm; then
- whiptail --title "Reset X11" --infobox "Reconfiguring LightDM..." 8 78
- sudo dpkg-reconfigure lightdm &>> "$LOG_FILE" || handle_error "Failed to reconfigure LightDM."
- fi
- # Prompt to restart display manager
- if confirm_action "Restart Display Manager" "Would you like to restart the display manager now? This will close all open applications."; then
- sudo systemctl restart lightdm &>> "$LOG_FILE" || handle_error "Failed to restart LightDM."
- else
- whiptail --title "Reset X11" --msgbox "X11 configuration has been reset. Please reboot your system to apply changes." 8 78
- fi
- whiptail --title "Reset X11" --msgbox "X11 configuration has been reset to the distribution default." 8 78
- log "X11 configuration reset successfully."
- }
- # Function to reset LightDM
- lightdm_reset() {
- if ! confirm_action "Reset LightDM" "This will reinstall LightDM and reset its configuration to default. Continue?"; then
- log "Reset LightDM cancelled by the user."
- return
- fi
- # Ensure backup directory exists
- mkdir -p "$BACKUP_DIR"
- # Backup existing LightDM configuration
- local lightdm_conf="/etc/lightdm/lightdm.conf"
- if [[ -f "$lightdm_conf" ]]; then
- sudo cp "$lightdm_conf" "$BACKUP_DIR/lightdm.conf.bak_$(date +%F_%T)" &>> "$LOG_FILE" || handle_error "Failed to backup LightDM configuration."
- log "Backed up LightDM configuration to $BACKUP_DIR/lightdm.conf.bak_$(date +%F_%T)."
- fi
- # Reinstall LightDM
- whiptail --title "Resetting LightDM" --infobox "Reinstalling LightDM..." 8 78
- sudo apt-get install --reinstall lightdm -y &>> "$LOG_FILE" || handle_error "Failed to reinstall LightDM."
- # Reconfigure LightDM to ensure it's the default display manager
- sudo dpkg-reconfigure lightdm &>> "$LOG_FILE" || handle_error "Failed to reconfigure LightDM."
- # Restart LightDM
- sudo systemctl restart lightdm &>> "$LOG_FILE" || handle_error "Failed to restart LightDM."
- whiptail --title "LightDM Reset" --msgbox "LightDM has been reset to its distribution default and restarted successfully." 8 78
- log "LightDM reset and restarted successfully."
- }
- # Function to make Wayland the default display server
- make_wayland_default() {
- # Check if GDM3 is installed
- if ! dpkg -s gdm3 &>/dev/null; then
- whiptail --title "Error" --msgbox "GDM3 is not installed. This script currently supports making Wayland default for GDM3 only." 8 78
- log "Make Wayland Default failed: GDM3 not installed."
- return
- fi
- # Backup existing GDM3 configuration
- local gdm_config="/etc/gdm3/custom.conf"
- if [[ -f "$gdm_config" ]]; then
- sudo cp "$gdm_config" "$BACKUP_DIR/custom.conf.bak_$(date +%F_%T)" &>> "$LOG_FILE" || handle_error "Failed to backup GDM3 configuration."
- log "Backed up GDM3 configuration to $BACKUP_DIR/custom.conf.bak_$(date +%F_%T)."
- fi
- # Enable Wayland in GDM3 configuration
- sudo sed -i 's/^#WaylandEnable=false/WaylandEnable=true/' "$gdm_config" || handle_error "Failed to enable Wayland in GDM3 configuration."
- log "Enabled Wayland in GDM3 configuration."
- # Remove Xorg configuration if exists
- if [[ -f "/etc/X11/xorg.conf" ]]; then
- sudo mv /etc/X11/xorg.conf "$BACKUP_DIR/xorg.conf.bak_$(date +%F_%T)" &>> "$LOG_FILE" || handle_error "Failed to backup Xorg configuration."
- log "Moved existing Xorg configuration to backup."
- fi
- # Restart GDM3 to apply changes
- sudo systemctl restart gdm3 &>> "$LOG_FILE" || handle_error "Failed to restart GDM3."
- whiptail --title "Make Wayland Default" --msgbox "Wayland has been set as the default display server. GDM3 has been restarted to apply changes." 8 78
- log "Wayland set as default display server and GDM3 restarted."
- }
- # Function to install or remove desktop environments
- desktop_environment_installer_remover() {
- # Refresh the installation status
- check_installed_desktops
- # Prepare checklist options
- local choices=()
- for DE in "${!DESKTOP_ENVS[@]}"; do
- local status="${DESKTOP_ENVS[$DE]}"
- if [[ "$status" == "installed" ]]; then
- choices+=("$DE" "Installed" "ON")
- else
- choices+=("$DE" "Not Installed" "OFF")
- fi
- done
- # Prompt user to select desktop environments to install/remove
- local selected_des
- selected_des=$(whiptail --title "Desktop Environment Installer/Remover" --checklist \
- "Select desktop environments to install or remove:" 20 80 12 \
- "${choices[@]}" 3>&1 1>&2 2>&3)
- # Check if user made a selection
- if [ -z "$selected_des" ]; then
- log "No desktop environments selected for installation/removal."
- return
- fi
- # Convert selection to an array
- read -r -a selected_des <<< "$(echo "$selected_des" | tr -d '"')"
- # Iterate through selected desktop environments
- for DE in "${selected_des[@]}"; do
- if [[ "${DESKTOP_ENVS[$DE]}" == "installed" ]]; then
- # Prompt to remove the desktop environment
- if confirm_action "Remove $DE" "Do you want to remove the $DE desktop environment?"; then
- whiptail --title "Removing $DE" --infobox "Removing $DE desktop environment..." 8 78
- sudo apt-get purge "${DESKTOP_ENVS[$DE]}" -y &>> "$LOG_FILE" || handle_error "Failed to remove $DE."
- sudo apt-get autoremove -y &>> "$LOG_FILE" || handle_error "Failed to autoremove dependencies after removing $DE."
- whiptail --title "Remove $DE" --msgbox "$DE has been removed successfully." 8 78
- log "$DE desktop environment removed successfully."
- else
- log "Removal of $DE cancelled by the user."
- fi
- else
- # Prompt to install the desktop environment
- if confirm_action "Install $DE" "Do you want to install the $DE desktop environment?"; then
- whiptail --title "Installing $DE" --infobox "Installing $DE desktop environment..." 8 78
- sudo apt-get install "${DESKTOP_ENVS[$DE]}" -y &>> "$LOG_FILE" || handle_error "Failed to install $DE."
- whiptail --title "Install $DE" --msgbox "$DE has been installed successfully." 8 78
- log "$DE desktop environment installed successfully."
- else
- log "Installation of $DE cancelled by the user."
- fi
- fi
- done
- # Refresh desktop environment status
- check_installed_desktops
- }
- # Function to attempt running startx
- startx_attempt() {
- whiptail --title "Startx Attempt" --msgbox "Attempting to start X server using startx. This will close all open applications." 8 78
- log "Attempting to start X server using startx."
- # Execute startx and log output
- startx &>> "$LOG_FILE" || handle_error "Failed to start X server with startx."
- whiptail --title "Startx Attempt" --msgbox "startx command executed. Check the log file for details." 8 78
- log "startx command executed."
- }
- # Function to repair Cinnamon desktop environment
- cinnamon_repair() {
- if ! dpkg -s cinnamon &>/dev/null && ! dpkg -s mint-meta-cinnamon &>/dev/null; then
- whiptail --title "Error" --msgbox "Cinnamon is not installed on your system." 8 78
- log "Cinnamon repair failed: Cinnamon is not installed."
- return
- fi
- whiptail --title "Cinnamon Repair" --infobox "Reinstalling Cinnamon packages..." 8 78
- sudo apt-get install --reinstall cinnamon mint-meta-cinnamon -y &>> "$LOG_FILE" || handle_error "Failed to reinstall Cinnamon packages."
- whiptail --title "Cinnamon Repair" --infobox "Resetting Cinnamon settings..." 8 78
- dconf reset -f /org/cinnamon/ &>> "$LOG_FILE" || handle_error "Failed to reset Cinnamon settings."
- whiptail --title "Cinnamon Repair" --msgbox "Cinnamon has been repaired and reset successfully." 8 78
- log "Cinnamon repaired and reset successfully."
- }
- # Function for Boot & Disk Management menu
- boot_disk_management_menu() {
- local choice
- choice=$(display_menu "Boot & Disk Management" "Choose an action:" \
- "1" "Optimize Boot Sequence" \
- "2" "Fix Slow Boot Issues" \
- "3" "Restore Original Boot Sequence" \
- "4" "Manually Adjust Boot Sequence" \
- "5" "Remove Linux Kernel Versions" \
- "6" "Check Disk Health" \
- "7" "Back to Main Menu")
- case $choice in
- 1) optimize_boot_sequence ;;
- 2) fix_slow_boot ;;
- 3) restore_to_distro_default ;;
- 4) manually_adjust_boot_sequence ;;
- 5) remove_kernel_versions ;;
- 6) check_disk_health ;;
- 7) main_menu ;;
- *) log "Invalid selection: $choice"; boot_disk_management_menu ;;
- esac
- }
- # Function to optimize boot sequence
- optimize_boot_sequence() {
- whiptail --title "Optimizing Boot Sequence" --infobox "Backing up current unit files..." 8 78
- sudo systemctl list-unit-files --state=enabled > "$BACKUP_DIR/unit_files_$(date +%F_%T).backup" || handle_error "Failed to backup unit files."
- declare -A SERVICE_CATEGORIES=(
- [system]="systemd-* udev*"
- [filesystem]="*.mount"
- [drivers]="*-drivers.*"
- [user]="user@*.service"
- [user_defined]="httpd* mysqld* sshd*"
- )
- local services_to_process=()
- for category in "${!SERVICE_CATEGORIES[@]}"; do
- for pattern in ${SERVICE_CATEGORIES[$category]}; do
- while IFS= read -r line; do
- services_to_process+=("$line")
- done < <(systemctl list-unit-files --state=enabled | grep "$pattern" | awk '{print $1}')
- done
- done
- local total_services=${#services_to_process[@]}
- local counter=0
- local error_occurred=0
- {
- for service in "${services_to_process[@]}"; do
- let counter+=1
- if ! sudo systemctl disable "$service" &>> "$LOG_FILE"; then
- error_occurred=1
- echo "XXX"
- echo "Failed disabling $service ($counter of $total_services)"
- echo "XXX"
- echo $((counter * 50 / total_services))
- break
- fi
- echo "XXX"
- echo "Disabling $service ($counter of $total_services)"
- echo "XXX"
- echo $((counter * 50 / total_services))
- done
- if (( error_occurred == 0 )); then
- for service in "${services_to_process[@]}"; do
- let counter+=1
- if ! sudo systemctl enable "$service" &>> "$LOG_FILE"; then
- error_occurred=1
- echo "XXX"
- echo "Failed enabling $service ($counter of $total_services)"
- echo "XXX"
- echo $((counter * 50 / total_services + 50))
- break
- fi
- echo "XXX"
- echo "Enabling $service ($counter of $total_services)"
- echo "XXX"
- echo $((counter * 50 / total_services + 50))
- done
- fi
- } | whiptail --gauge "Optimizing boot sequence..." 20 70 0
- if (( error_occurred )); then
- whiptail --title "Error" --msgbox "An error occurred during the optimization process. Check the log file for details." 8 78
- log "Boot sequence optimization encountered errors."
- else
- whiptail --title "Optimize Boot Sequence" --msgbox "Boot sequence optimized successfully." 8 78
- log "Boot sequence optimized successfully."
- fi
- }
- # Function to fix slow boot issues
- fix_slow_boot() {
- whiptail --title "Fix Slow Boot Issues" --infobox "Backing up GRUB configuration..." 8 78
- sudo cp /etc/default/grub "$BACKUP_DIR/grub.bak_$(date +%F_%T)" || handle_error "Failed to backup GRUB configuration."
- # Disable plymouth-quit-wait.service
- sudo systemctl disable plymouth-quit-wait.service &>> "$LOG_FILE" || handle_error "Failed to disable plymouth-quit-wait.service."
- log "Disabled plymouth-quit-wait.service."
- # Reduce GRUB timeout
- sudo sed -i 's/^GRUB_TIMEOUT=.*/GRUB_TIMEOUT=5/' /etc/default/grub || handle_error "Failed to set GRUB_TIMEOUT."
- sudo update-grub &>> "$LOG_FILE" || handle_error "Failed to update GRUB."
- # Optimize systemd services
- local slow_units
- slow_units=$(systemd-analyze blame | head -n 5 | awk '{print $2}')
- for unit in $slow_units; do
- if confirm_action "Disable $unit" "Do you want to disable the slow service: $unit?"; then
- sudo systemctl disable "$unit" &>> "$LOG_FILE" || handle_error "Failed to disable $unit."
- log "Disabled slow service: $unit."
- fi
- done
- # Check for failed systemd units
- local failed_units
- failed_units=$(systemctl --failed --no-legend | grep ".service" | awk '{print $1}')
- if [ -n "$failed_units" ]; then
- whiptail --title "Failed Services" --msgbox "The following services have failed and may require manual intervention:\n$failed_units" 10 78
- log "Failed services detected: $failed_units."
- fi
- whiptail --title "Fix Slow Boot" --msgbox "Attempted to fix slow boot issues. Some changes might require a reboot." 8 78
- log "Attempted to fix slow boot issues."
- }
- # Function to restore boot sequence to distribution default
- restore_to_distro_default() {
- whiptail --title "Restore Boot Sequence" --infobox "Restoring boot sequence to distribution defaults..." 8 78
- sudo systemctl preset-all &>> "$LOG_FILE" || handle_error "Failed to preset all systemd unit files."
- sudo update-grub &>> "$LOG_FILE" || handle_error "Failed to update GRUB."
- whiptail --title "Restore Boot Sequence" --msgbox "Boot sequence has been restored to distribution defaults successfully." 8 78
- log "Boot sequence restored to distribution defaults."
- }
- # Function to manually adjust boot sequence
- manually_adjust_boot_sequence() {
- # List all enabled services
- local services
- services=$(systemctl list-unit-files --state=enabled | awk '{print $1}' | grep '.service')
- # Prepare checklist options
- local choices=()
- for svc in $services; do
- choices+=("$svc" "" "OFF")
- done
- # Prompt user to select services to enable/disable
- local selected_services
- selected_services=$(whiptail --title "Adjust Boot Sequence" --checklist \
- "Select services to toggle (use space to select):" 20 100 15 \
- "${choices[@]}" 3>&1 1>&2 2>&3)
- # Check if user made a selection
- if [ -z "$selected_services" ]; then
- log "No services selected for manual adjustment."
- return
- fi
- # Convert selection to an array
- read -r -a selected_services <<< "$(echo "$selected_services" | tr -d '"')"
- # Iterate through selected services
- for svc in "${selected_services[@]}"; do
- if systemctl is-enabled --quiet "$svc"; then
- if confirm_action "Disable $svc" "Do you want to disable the service: $svc?"; then
- sudo systemctl disable "$svc" &>> "$LOG_FILE" || handle_error "Failed to disable $svc."
- log "Disabled service: $svc."
- fi
- else
- if confirm_action "Enable $svc" "Do you want to enable the service: $svc?"; then
- sudo systemctl enable "$svc" &>> "$LOG_FILE" || handle_error "Failed to enable $svc."
- log "Enabled service: $svc."
- fi
- fi
- done
- whiptail --title "Adjust Boot Sequence" --msgbox "Boot sequence has been manually adjusted." 8 78
- log "Boot sequence manually adjusted."
- }
- # Function to remove old Linux kernel versions
- remove_kernel_versions() {
- # Get current kernel version
- local current_kernel
- current_kernel=$(uname -r)
- # List all installed kernel packages excluding the current one
- local kernels
- kernels=$(dpkg --list | grep 'linux-image-[0-9]' | awk '{print $2}' | grep -v "$current_kernel")
- if [ -z "$kernels" ]; then
- whiptail --title "Remove Kernel" --msgbox "No additional kernels found to remove." 8 78
- log "No additional kernels found for removal."
- return
- fi
- # Prepare checklist options
- local choices=()
- for kernel in $kernels; do
- choices+=("$kernel" "Installed" "OFF")
- done
- # Prompt user to select kernels to remove
- local selected_kernels
- selected_kernels=$(whiptail --title "Remove Kernel Versions" --checklist \
- "Select kernels to uninstall:" 20 100 15 \
- "${choices[@]}" 3>&1 1>&2 2>&3)
- # Check if user made a selection
- if [ -z "$selected_kernels" ]; then
- log "No kernels selected for removal."
- return
- fi
- # Convert selection to an array
- read -r -a selected_kernels <<< "$(echo "$selected_kernels" | tr -d '"')"
- # Iterate through selected kernels and remove them
- for kernel in "${selected_kernels[@]}"; do
- if confirm_action "Remove $kernel" "Are you sure you want to remove $kernel?"; then
- whiptail --title "Removing $kernel" --infobox "Removing $kernel..." 8 78
- sudo apt-get purge "$kernel" -y &>> "$LOG_FILE" || handle_error "Failed to remove $kernel."
- sudo apt-get autoremove -y &>> "$LOG_FILE" || handle_error "Failed to autoremove dependencies after removing $kernel."
- log "Removed kernel: $kernel."
- fi
- done
- # Update GRUB after kernel removal
- sudo update-grub &>> "$LOG_FILE" || handle_error "Failed to update GRUB after kernel removal."
- whiptail --title "Remove Kernel Versions" --msgbox "Selected kernels have been removed successfully. Please reboot your system." 8 78
- log "Selected kernels removed successfully."
- }
- # Function to check disk health using smartctl
- check_disk_health() {
- # Ensure smartmontools is installed
- if ! dpkg -s smartmontools &>/dev/null; then
- if confirm_action "Install smartmontools" "smartmontools is not installed. Do you want to install it now?"; then
- sudo apt-get update && sudo apt-get install smartmontools -y &>> "$LOG_FILE" || handle_error "Failed to install smartmontools."
- log "smartmontools installed successfully."
- else
- log "smartmontools not installed. Cannot check disk health."
- whiptail --title "Error" --msgbox "smartmontools is required to check disk health." 8 78
- return
- fi
- fi
- # List available disks excluding loop devices
- local disks=($(lsblk -d -o NAME,TYPE | awk '$2=="disk"{print $1}'))
- if [ ${#disks[@]} -eq 0 ]; then
- whiptail --title "Error" --msgbox "No disks found to check." 8 78
- log "No disks found for health check."
- return
- fi
- # Prepare radiolist options
- local choices=()
- for disk in "${disks[@]}"; do
- local size
- size=$(lsblk -d -o SIZE -n "/dev/$disk")
- choices+=("/dev/$disk" "Size: $size" OFF)
- done
- # Prompt user to select a disk
- local selected_disk
- selected_disk=$(whiptail --title "Select Disk for Health Check" --radiolist \
- "Choose a disk to check its health:" 20 78 10 \
- "${choices[@]}" 3>&1 1>&2 2>&3)
- # Check if user made a selection
- if [ -z "$selected_disk" ]; then
- log "Disk health check cancelled by the user."
- return
- fi
- selected_disk=$(echo "$selected_disk" | tr -d '"')
- # Run SMART health check
- whiptail --title "Disk Health Check" --infobox "Running SMART health check on $selected_disk..." 8 78
- local health_report
- health_report=$(sudo smartctl -H "$selected_disk" 2>> "$LOG_FILE") || handle_error "Failed to retrieve SMART health report for $selected_disk."
- # Parse health status
- local health_status
- health_status=$(echo "$health_report" | grep -oP 'SMART overall-health self-assessment test result: \K.*')
- # Interpret the health status
- local message=""
- if [[ "$health_status" =~ ^(PASSED|OK)$ ]]; then
- message="✅ Your disk ($selected_disk) is in good health."
- else
- message="⚠️ Warning: Potential issues detected with disk ($selected_disk). Please investigate further."
- fi
- # Display the result
- whiptail --title "Disk Health Check" --msgbox "$message\n\n$health_report" 20 78
- log "Disk health check for $selected_disk: $health_status."
- }
- # Function for Network & Security menu
- network_security_menu() {
- local choice
- choice=$(display_menu "Network & Security" "Choose an action:" \
- "1" "Reset Network Configuration" \
- "2" "Reset Firewall Rules" \
- "3" "Back to Main Menu")
- case $choice in
- 1) reset_network_configuration ;;
- 2) reset_firewall_rules ;;
- 3) main_menu ;;
- *) log "Invalid selection: $choice"; network_security_menu ;;
- esac
- }
- # Function to reset network configuration
- reset_network_configuration() {
- if ! confirm_action "Reset Network Configuration" "Are you sure you want to reset network configuration to default? This will disrupt all active network connections."; then
- log "Reset network configuration cancelled by the user."
- return
- fi
- whiptail --title "Reset Network Configuration" --infobox "Resetting network configuration..." 8 78
- sudo systemctl restart NetworkManager &>> "$LOG_FILE" || handle_error "Failed to restart NetworkManager."
- # Optionally, reset network settings using nmcli
- sudo nmcli networking off &>> "$LOG_FILE" || handle_error "Failed to turn off networking."
- sudo nmcli networking on &>> "$LOG_FILE" || handle_error "Failed to turn on networking."
- whiptail --title "Reset Network Configuration" --msgbox "Network configuration has been reset successfully." 8 78
- log "Network configuration reset successfully."
- }
- # Function to reset firewall rules to default
- reset_firewall_rules() {
- if ! confirm_action "Reset Firewall Rules" "Are you sure you want to reset all firewall rules to default? This will remove all custom rules."; then
- log "Reset firewall rules cancelled by the user."
- return
- fi
- whiptail --title "Reset Firewall Rules" --infobox "Resetting firewall rules..." 8 78
- # Flush iptables rules
- sudo iptables -F &>> "$LOG_FILE" || handle_error "Failed to flush iptables rules."
- sudo iptables -X &>> "$LOG_FILE" || handle_error "Failed to delete iptables chains."
- sudo iptables -t nat -F &>> "$LOG_FILE" || handle_error "Failed to flush NAT table."
- sudo iptables -t nat -X &>> "$LOG_FILE" || handle_error "Failed to delete NAT chains."
- # Reset default policies
- sudo iptables -P INPUT ACCEPT &>> "$LOG_FILE" || handle_error "Failed to set INPUT policy."
- sudo iptables -P FORWARD ACCEPT &>> "$LOG_FILE" || handle_error "Failed to set FORWARD policy."
- sudo iptables -P OUTPUT ACCEPT &>> "$LOG_FILE" || handle_error "Failed to set OUTPUT policy."
- whiptail --title "Reset Firewall Rules" --msgbox "Firewall rules have been reset to default successfully." 8 78
- log "Firewall rules reset to default successfully."
- }
- # Function for System Tools & Utilities menu
- system_tools_utilities_menu() {
- local choice
- choice=$(display_menu "System Tools & Utilities" "Choose an action:" \
- "1" "System Info" \
- "2" "Repair File System" \
- "3" "Clear System Logs" \
- "4" "Reset User Password" \
- "5" "The Final Solution" \
- "6" "Back to Main Menu")
- case $choice in
- 1) system_info ;;
- 2) repair_file_system ;;
- 3) clear_system_logs ;;
- 4) reset_user_password ;;
- 5) the_final_solution ;;
- 6) main_menu ;;
- *) log "Invalid selection: $choice"; system_tools_utilities_menu ;;
- esac
- }
- # Function to display system information
- system_info() {
- # Install required packages if missing
- local required_pkgs=("neofetch" "lscpu")
- local missing_pkgs=()
- for pkg in "${required_pkgs[@]}"; do
- if ! dpkg -s "$pkg" &>/dev/null; then
- missing_pkgs+=("$pkg")
- fi
- done
- if [ ${#missing_pkgs[@]} -ne 0 ]; then
- if confirm_action "Install Missing Packages" "The following packages are missing: ${missing_pkgs[*]}. Install them now?"; then
- sudo apt-get update && sudo apt-get install -y "${missing_pkgs[@]}" &>> "$LOG_FILE" || handle_error "Failed to install required packages."
- log "Installed missing packages: ${missing_pkgs[*]}."
- else
- whiptail --title "System Info" --msgbox "Cannot display system information without required packages." 8 78
- log "System info display failed: Required packages missing."
- return
- fi
- fi
- # Collect system information
- local sysinfo=""
- sysinfo+="$(neofetch --stdout)\n"
- sysinfo+="\nCPU Information:\n$(lscpu)\n"
- sysinfo+="\nMemory Information:\n$(free -h)\n"
- sysinfo+="\nDisk Usage:\n$(df -h | grep '^/dev/')\n"
- sysinfo+="\nKernel Information:\n$(uname -a)\n"
- # Display the information in a scrollable box
- whiptail --title "System Information" --scrolltext --msgbox "$sysinfo" 20 100
- log "Displayed system information."
- }
- # Function to repair file system
- repair_file_system() {
- # Prompt user to select a disk
- local disks=($(lsblk -d -o NAME,TYPE | awk '$2=="disk"{print $1}'))
- if [ ${#disks[@]} -eq 0 ]; then
- whiptail --title "Error" --msgbox "No disks found to repair." 8 78
- log "No disks found for file system repair."
- return
- fi
- # Prepare radiolist options
- local choices=()
- for disk in "${disks[@]}"; do
- local size
- size=$(lsblk -d -o SIZE -n "/dev/$disk")
- choices+=("/dev/$disk" "Size: $size" OFF)
- done
- # Prompt user to select a disk
- local selected_disk
- selected_disk=$(whiptail --title "Repair File System" --radiolist \
- "Select a disk to repair its file system:" 20 80 10 \
- "${choices[@]}" 3>&1 1>&2 2>&3)
- # Check if user made a selection
- if [ -z "$selected_disk" ]; then
- log "File system repair cancelled by the user."
- return
- fi
- selected_disk=$(echo "$selected_disk" | tr -d '"')
- # Confirm the repair operation
- if ! confirm_action "Confirm Repair" "This will check and attempt to repair the file system on $selected_disk. It's recommended to close all other applications before proceeding. Continue?"; then
- log "File system repair cancelled by the user."
- return
- fi
- # Inform user to perform repair in terminal
- whiptail --title "Repair File System" --msgbox "Please perform the file system repair on $selected_disk manually in the terminal. Press OK to continue." 8 78
- log "Prompted user to perform file system repair manually."
- # Open a terminal window to run fsck (assuming gnome-terminal is available)
- if command -v gnome-terminal &>/dev/null; then
- gnome-terminal -- bash -c "sudo fsck -f $selected_disk; exec bash" &
- log "Opened gnome-terminal for fsck on $selected_disk."
- else
- # Fallback to executing fsck in the current terminal
- sudo fsck -f "$selected_disk" &>> "$LOG_FILE" || handle_error "fsck failed on $selected_disk."
- log "fsck executed on $selected_disk."
- fi
- whiptail --title "Repair File System" --msgbox "File system repair initiated for $selected_disk. Please monitor the terminal for progress." 8 78
- }
- # Function to clear system logs
- clear_system_logs() {
- if ! confirm_action "Clear System Logs" "Are you sure you want to clear all system logs? This action cannot be undone."; then
- log "Clear system logs cancelled by the user."
- return
- fi
- whiptail --title "Clearing System Logs" --infobox "Clearing system logs..." 8 78
- sudo journalctl --rotate &>> "$LOG_FILE" || handle_error "Failed to rotate journal logs."
- sudo journalctl --vacuum-time=1s &>> "$LOG_FILE" || handle_error "Failed to vacuum journal logs."
- whiptail --title "Clear System Logs" --msgbox "System logs have been cleared successfully." 8 78
- log "System logs cleared successfully."
- }
- # Function to reset a user's password
- reset_user_password() {
- # Prompt for the username
- local username
- username=$(whiptail --title "Reset User Password" --inputbox "Enter the username to reset the password for:" 8 60 3>&1 1>&2 2>&3)
- if [ $? -ne 0 ]; then
- log "Reset user password cancelled by the user."
- return
- fi
- if [ -z "$username" ]; then
- whiptail --title "Error" --msgbox "No username entered. Please provide a valid username." 8 78
- log "Reset user password failed: No username entered."
- return
- fi
- # Check if the user exists
- if ! id "$username" &>/dev/null; then
- whiptail --title "Error" --msgbox "User '$username' does not exist." 8 78
- log "Reset user password failed: User '$username' does not exist."
- return
- fi
- # Prompt user to enter a new password
- local new_password
- new_password=$(whiptail --title "Reset User Password" --passwordbox "Enter a new password for $username:" 10 60 3>&1 1>&2 2>&3)
- if [ $? -ne 0 ]; then
- log "Reset user password cancelled during password entry."
- return
- fi
- if [ -z "$new_password" ]; then
- whiptail --title "Error" --msgbox "No password entered. Please provide a valid password." 8 78
- log "Reset user password failed: No password entered."
- return
- fi
- # Reset the user's password
- echo "$username:$new_password" | sudo chpasswd &>> "$LOG_FILE" || handle_error "Failed to reset password for $username."
- whiptail --title "Reset User Password" --msgbox "Password for user '$username' has been reset successfully." 8 78
- log "Password for user '$username' reset successfully."
- }
- # Function for the final solution (extreme measures)
- the_final_solution() {
- # Warn the user about the consequences
- whiptail --title "Warning: The Final Solution" --msgbox "This action will remove everything, including plymouth, xorg, gnome (if installed), cinnamon (if installed), kde (if installed), gdm3, and any other configurations. All original configurations for certain tools will be lost. Proceed with caution and only use this as a last resort." 10 78
- # Ask for user confirmation
- if confirm_action "Confirm The Final Solution" "This action is non-reversible. Are you sure you want to proceed with the last resort fresh installation?"; then
- # Purge critical packages
- whiptail --title "Executing The Final Solution" --infobox "Purging critical packages..." 8 78
- sudo apt-get purge '^nvidia.*' '^plymouth.*' '^xorg.*' '^gnome.*' '^cinnamon.*' '^kde.*' '^gdm3.*' '^mate.*' '^xfce.*' '^ubuntu.*' -y &>> "$LOG_FILE" || handle_error "Failed to purge critical packages."
- # Reinstall essential packages
- whiptail --title "Reinstalling Essential Packages" --infobox "Reinstalling plymouth, xorg, and cinnamon..." 8 78
- sudo apt-get install plymouth xorg cinnamon -y &>> "$LOG_FILE" || handle_error "Failed to reinstall essential packages."
- whiptail --title "The Final Solution" --msgbox "The system has been reset to a fresh installation state. Please reboot your system." 8 78
- log "The Final Solution executed successfully."
- else
- log "The Final Solution cancelled by the user."
- main_menu
- fi
- }
- # Function to check installed desktop environments
- check_installed_desktops() {
- for DE in "${!DESKTOP_ENVS[@]}"; do
- # Initial assumption is that it's not installed
- DESKTOP_ENVS[$DE]="not installed"
- # Check if the package is installed
- if dpkg -s "${DESKTOP_ENVS[$DE]}" &>/dev/null; then
- DESKTOP_ENVS[$DE]="installed"
- else
- # Additional checks can be added here if necessary
- :
- fi
- done
- }
- # Function for Boot & Disk Management menu
- boot_disk_management_menu() {
- local choice
- choice=$(display_menu "Boot & Disk Management" "Choose an action:" \
- "1" "Optimize Boot Sequence" \
- "2" "Fix Slow Boot Issues" \
- "3" "Restore Original Boot Sequence" \
- "4" "Manually Adjust Boot Sequence" \
- "5" "Remove Linux Kernel Versions" \
- "6" "Check Disk Health" \
- "7" "Back to Main Menu")
- case $choice in
- 1) optimize_boot_sequence ;;
- 2) fix_slow_boot ;;
- 3) restore_to_distro_default ;;
- 4) manually_adjust_boot_sequence ;;
- 5) remove_kernel_versions ;;
- 6) check_disk_health ;;
- 7) main_menu ;;
- *) log "Invalid selection: $choice"; boot_disk_management_menu ;;
- esac
- }
- # Function to optimize boot sequence
- optimize_boot_sequence() {
- whiptail --title "Optimizing Boot Sequence" --infobox "Backing up current unit files..." 8 78
- sudo systemctl list-unit-files --state=enabled > "$BACKUP_DIR/unit_files_$(date +%F_%T).backup" || handle_error "Failed to backup unit files."
- declare -A SERVICE_CATEGORIES=(
- [system]="systemd-* udev*"
- [filesystem]="*.mount"
- [drivers]="*-drivers.*"
- [user]="user@*.service"
- [user_defined]="httpd* mysqld* sshd*"
- )
- local services_to_process=()
- for category in "${!SERVICE_CATEGORIES[@]}"; do
- for pattern in ${SERVICE_CATEGORIES[$category]}; do
- while IFS= read -r line; do
- services_to_process+=("$line")
- done < <(systemctl list-unit-files --state=enabled | grep "$pattern" | awk '{print $1}')
- done
- done
- local total_services=${#services_to_process[@]}
- local counter=0
- local error_occurred=0
- {
- for service in "${services_to_process[@]}"; do
- let counter+=1
- if ! sudo systemctl disable "$service" &>> "$LOG_FILE"; then
- error_occurred=1
- echo "XXX"
- echo "Failed disabling $service ($counter of $total_services)"
- echo "XXX"
- echo $((counter * 50 / total_services))
- break
- fi
- echo "XXX"
- echo "Disabling $service ($counter of $total_services)"
- echo "XXX"
- echo $((counter * 50 / total_services))
- done
- if (( error_occurred == 0 )); then
- for service in "${services_to_process[@]}"; do
- let counter+=1
- if ! sudo systemctl enable "$service" &>> "$LOG_FILE"; then
- error_occurred=1
- echo "XXX"
- echo "Failed enabling $service ($counter of $total_services)"
- echo "XXX"
- echo $((counter * 50 / total_services + 50))
- break
- fi
- echo "XXX"
- echo "Enabling $service ($counter of $total_services)"
- echo "XXX"
- echo $((counter * 50 / total_services + 50))
- done
- fi
- } | whiptail --gauge "Optimizing boot sequence..." 20 70 0
- if (( error_occurred )); then
- whiptail --title "Error" --msgbox "An error occurred during the optimization process. Check the log file for details." 8 78
- log "Boot sequence optimization encountered errors."
- else
- whiptail --title "Optimize Boot Sequence" --msgbox "Boot sequence optimized successfully." 8 78
- log "Boot sequence optimized successfully."
- fi
- }
- # Function to fix slow boot issues
- fix_slow_boot() {
- whiptail --title "Fix Slow Boot Issues" --infobox "Backing up GRUB configuration..." 8 78
- sudo cp /etc/default/grub "$BACKUP_DIR/grub.bak_$(date +%F_%T)" || handle_error "Failed to backup GRUB configuration."
- # Disable plymouth-quit-wait.service
- sudo systemctl disable plymouth-quit-wait.service &>> "$LOG_FILE" || handle_error "Failed to disable plymouth-quit-wait.service."
- log "Disabled plymouth-quit-wait.service."
- # Reduce GRUB timeout
- sudo sed -i 's/^GRUB_TIMEOUT=.*/GRUB_TIMEOUT=5/' /etc/default/grub || handle_error "Failed to set GRUB_TIMEOUT."
- sudo update-grub &>> "$LOG_FILE" || handle_error "Failed to update GRUB."
- # Optimize systemd services
- local slow_units
- slow_units=$(systemd-analyze blame | head -n 5 | awk '{print $2}')
- for unit in $slow_units; do
- if confirm_action "Disable $unit" "Do you want to disable the slow service: $unit?"; then
- sudo systemctl disable "$unit" &>> "$LOG_FILE" || handle_error "Failed to disable $unit."
- log "Disabled slow service: $unit."
- fi
- done
- # Check for failed systemd units
- local failed_units
- failed_units=$(systemctl --failed --no-legend | grep ".service" | awk '{print $1}')
- if [ -n "$failed_units" ]; then
- whiptail --title "Failed Services" --msgbox "The following services have failed and may require manual intervention:\n$failed_units" 10 78
- log "Failed services detected: $failed_units."
- fi
- whiptail --title "Fix Slow Boot" --msgbox "Attempted to fix slow boot issues. Some changes might require a reboot." 8 78
- log "Attempted to fix slow boot issues."
- }
- # Function to restore boot sequence to distribution default
- restore_to_distro_default() {
- whiptail --title "Restore Boot Sequence" --infobox "Restoring boot sequence to distribution defaults..." 8 78
- sudo systemctl preset-all &>> "$LOG_FILE" || handle_error "Failed to preset all systemd unit files."
- sudo update-grub &>> "$LOG_FILE" || handle_error "Failed to update GRUB."
- whiptail --title "Restore Boot Sequence" --msgbox "Boot sequence has been restored to distribution defaults successfully." 8 78
- log "Boot sequence restored to distribution defaults."
- }
- # Function to manually adjust boot sequence
- manually_adjust_boot_sequence() {
- # List all enabled services
- local services
- services=$(systemctl list-unit-files --state=enabled | awk '{print $1}' | grep '.service')
- # Prepare checklist options
- local choices=()
- for svc in $services; do
- choices+=("$svc" "" "OFF")
- done
- # Prompt user to select services to enable/disable
- local selected_services
- selected_services=$(whiptail --title "Adjust Boot Sequence" --checklist \
- "Select services to toggle (use space to select):" 20 100 15 \
- "${choices[@]}" 3>&1 1>&2 2>&3)
- # Check if user made a selection
- if [ -z "$selected_services" ]; then
- log "No services selected for manual adjustment."
- return
- fi
- # Convert selection to an array
- read -r -a selected_services <<< "$(echo "$selected_services" | tr -d '"')"
- # Iterate through selected services
- for svc in "${selected_services[@]}"; do
- if systemctl is-enabled --quiet "$svc"; then
- if confirm_action "Disable $svc" "Do you want to disable the service: $svc?"; then
- sudo systemctl disable "$svc" &>> "$LOG_FILE" || handle_error "Failed to disable $svc."
- log "Disabled service: $svc."
- fi
- else
- if confirm_action "Enable $svc" "Do you want to enable the service: $svc?"; then
- sudo systemctl enable "$svc" &>> "$LOG_FILE" || handle_error "Failed to enable $svc."
- log "Enabled service: $svc."
- fi
- fi
- done
- whiptail --title "Adjust Boot Sequence" --msgbox "Boot sequence has been manually adjusted." 8 78
- log "Boot sequence manually adjusted."
- }
- # Function to remove old Linux kernel versions
- remove_kernel_versions() {
- # Get current kernel version
- local current_kernel
- current_kernel=$(uname -r)
- # List all installed kernel packages excluding the current one
- local kernels
- kernels=$(dpkg --list | grep 'linux-image-[0-9]' | awk '{print $2}' | grep -v "$current_kernel")
- if [ -z "$kernels" ]; then
- whiptail --title "Remove Kernel" --msgbox "No additional kernels found to remove." 8 78
- log "No additional kernels found for removal."
- return
- fi
- # Prepare checklist options
- local choices=()
- for kernel in $kernels; do
- choices+=("$kernel" "Installed" "OFF")
- done
- # Prompt user to select kernels to remove
- local selected_kernels
- selected_kernels=$(whiptail --title "Remove Kernel Versions" --checklist \
- "Select kernels to uninstall:" 20 100 15 \
- "${choices[@]}" 3>&1 1>&2 2>&3)
- # Check if user made a selection
- if [ -z "$selected_kernels" ]; then
- log "No kernels selected for removal."
- return
- fi
- # Convert selection to an array
- read -r -a selected_kernels <<< "$(echo "$selected_kernels" | tr -d '"')"
- # Iterate through selected kernels and remove them
- for kernel in "${selected_kernels[@]}"; do
- if confirm_action "Remove $kernel" "Are you sure you want to remove $kernel?"; then
- whiptail --title "Removing $kernel" --infobox "Removing $kernel..." 8 78
- sudo apt-get purge "$kernel" -y &>> "$LOG_FILE" || handle_error "Failed to remove $kernel."
- sudo apt-get autoremove -y &>> "$LOG_FILE" || handle_error "Failed to autoremove dependencies after removing $kernel."
- log "Removed kernel: $kernel."
- fi
- done
- # Update GRUB after kernel removal
- sudo update-grub &>> "$LOG_FILE" || handle_error "Failed to update GRUB after kernel removal."
- whiptail --title "Remove Kernel Versions" --msgbox "Selected kernels have been removed successfully. Please reboot your system." 8 78
- log "Selected kernels removed successfully."
- }
- # Function to check disk health using smartctl
- check_disk_health() {
- # Ensure smartmontools is installed
- if ! dpkg -s smartmontools &>/dev/null; then
- if confirm_action "Install smartmontools" "smartmontools is not installed. Do you want to install it now?"; then
- sudo apt-get update && sudo apt-get install smartmontools -y &>> "$LOG_FILE" || handle_error "Failed to install smartmontools."
- log "smartmontools installed successfully."
- else
- log "smartmontools not installed. Cannot check disk health."
- whiptail --title "Error" --msgbox "smartmontools is required to check disk health." 8 78
- return
- fi
- fi
- # List available disks excluding loop devices
- local disks=($(lsblk -d -o NAME,TYPE | awk '$2=="disk"{print $1}'))
- if [ ${#disks[@]} -eq 0 ]; then
- whiptail --title "Error" --msgbox "No disks found to check." 8 78
- log "No disks found for health check."
- return
- fi
- # Prepare radiolist options
- local choices=()
- for disk in "${disks[@]}"; do
- local size
- size=$(lsblk -d -o SIZE -n "/dev/$disk")
- choices+=("/dev/$disk" "Size: $size" OFF)
- done
- # Prompt user to select a disk
- local selected_disk
- selected_disk=$(whiptail --title "Select Disk for Health Check" --radiolist \
- "Choose a disk to check its health:" 20 78 10 \
- "${choices[@]}" 3>&1 1>&2 2>&3)
- # Check if user made a selection
- if [ -z "$selected_disk" ]; then
- log "Disk health check cancelled by the user."
- return
- fi
- selected_disk=$(echo "$selected_disk" | tr -d '"')
- # Run SMART health check
- whiptail --title "Disk Health Check" --infobox "Running SMART health check on $selected_disk..." 8 78
- local health_report
- health_report=$(sudo smartctl -H "$selected_disk" 2>> "$LOG_FILE") || handle_error "Failed to retrieve SMART health report for $selected_disk."
- # Parse health status
- local health_status
- health_status=$(echo "$health_report" | grep -oP 'SMART overall-health self-assessment test result: \K.*')
- # Interpret the health status
- local message=""
- if [[ "$health_status" =~ ^(PASSED|OK)$ ]]; then
- message="✅ Your disk ($selected_disk) is in good health."
- else
- message="⚠️ Warning: Potential issues detected with disk ($selected_disk). Please investigate further."
- fi
- # Display the result
- whiptail --title "Disk Health Check" --msgbox "$message\n\n$health_report" 20 78
- log "Disk health check for $selected_disk: $health_status."
- }
- # Function for Network & Security menu
- network_security_menu() {
- local choice
- choice=$(display_menu "Network & Security" "Choose an action:" \
- "1" "Reset Network Configuration" \
- "2" "Reset Firewall Rules" \
- "3" "Back to Main Menu")
- case $choice in
- 1) reset_network_configuration ;;
- 2) reset_firewall_rules ;;
- 3) main_menu ;;
- *) log "Invalid selection: $choice"; network_security_menu ;;
- esac
- }
- # Function to reset network configuration
- reset_network_configuration() {
- if ! confirm_action "Reset Network Configuration" "Are you sure you want to reset network configuration to default? This will disrupt all active network connections."; then
- log "Reset network configuration cancelled by the user."
- return
- fi
- whiptail --title "Reset Network Configuration" --infobox "Resetting network configuration..." 8 78
- sudo systemctl restart NetworkManager &>> "$LOG_FILE" || handle_error "Failed to restart NetworkManager."
- # Optionally, reset network settings using nmcli
- sudo nmcli networking off &>> "$LOG_FILE" || handle_error "Failed to turn off networking."
- sudo nmcli networking on &>> "$LOG_FILE" || handle_error "Failed to turn on networking."
- whiptail --title "Reset Network Configuration" --msgbox "Network configuration has been reset successfully." 8 78
- log "Network configuration reset successfully."
- }
- # Function to reset firewall rules to default
- reset_firewall_rules() {
- if ! confirm_action "Reset Firewall Rules" "Are you sure you want to reset all firewall rules to default? This will remove all custom rules."; then
- log "Reset firewall rules cancelled by the user."
- return
- fi
- whiptail --title "Reset Firewall Rules" --infobox "Resetting firewall rules..." 8 78
- # Flush iptables rules
- sudo iptables -F &>> "$LOG_FILE" || handle_error "Failed to flush iptables rules."
- sudo iptables -X &>> "$LOG_FILE" || handle_error "Failed to delete iptables chains."
- sudo iptables -t nat -F &>> "$LOG_FILE" || handle_error "Failed to flush NAT table."
- sudo iptables -t nat -X &>> "$LOG_FILE" || handle_error "Failed to delete NAT chains."
- # Reset default policies
- sudo iptables -P INPUT ACCEPT &>> "$LOG_FILE" || handle_error "Failed to set INPUT policy."
- sudo iptables -P FORWARD ACCEPT &>> "$LOG_FILE" || handle_error "Failed to set FORWARD policy."
- sudo iptables -P OUTPUT ACCEPT &>> "$LOG_FILE" || handle_error "Failed to set OUTPUT policy."
- whiptail --title "Reset Firewall Rules" --msgbox "Firewall rules have been reset to default successfully." 8 78
- log "Firewall rules reset to default successfully."
- }
- # Function for System Tools & Utilities menu
- system_tools_utilities_menu() {
- local choice
- choice=$(display_menu "System Tools & Utilities" "Choose an action:" \
- "1" "System Info" \
- "2" "Repair File System" \
- "3" "Clear System Logs" \
- "4" "Reset User Password" \
- "5" "The Final Solution" \
- "6" "Back to Main Menu")
- case $choice in
- 1) system_info ;;
- 2) repair_file_system ;;
- 3) clear_system_logs ;;
- 4) reset_user_password ;;
- 5) the_final_solution ;;
- 6) main_menu ;;
- *) log "Invalid selection: $choice"; system_tools_utilities_menu ;;
- esac
- }
- # Function to display system information
- system_info() {
- # Install required packages if missing
- local required_pkgs=("neofetch" "lscpu")
- local missing_pkgs=()
- for pkg in "${required_pkgs[@]}"; do
- if ! dpkg -s "$pkg" &>/dev/null; then
- missing_pkgs+=("$pkg")
- fi
- done
- if [ ${#missing_pkgs[@]} -ne 0 ]; then
- if confirm_action "Install Missing Packages" "The following packages are missing: ${missing_pkgs[*]}. Install them now?"; then
- sudo apt-get update && sudo apt-get install -y "${missing_pkgs[@]}" &>> "$LOG_FILE" || handle_error "Failed to install required packages."
- log "Installed missing packages: ${missing_pkgs[*]}."
- else
- whiptail --title "System Info" --msgbox "Cannot display system information without required packages." 8 78
- log "System info display failed: Required packages missing."
- return
- fi
- fi
- # Collect system information
- local sysinfo=""
- sysinfo+="$(neofetch --stdout)\n"
- sysinfo+="\nCPU Information:\n$(lscpu)\n"
- sysinfo+="\nMemory Information:\n$(free -h)\n"
- sysinfo+="\nDisk Usage:\n$(df -h | grep '^/dev/')\n"
- sysinfo+="\nKernel Information:\n$(uname -a)\n"
- # Display the information in a scrollable box
- whiptail --title "System Information" --scrolltext --msgbox "$sysinfo" 20 100
- log "Displayed system information."
- }
- # Function to repair file system
- repair_file_system() {
- # Prompt user to select a disk
- local disks=($(lsblk -d -o NAME,TYPE | awk '$2=="disk"{print $1}'))
- if [ ${#disks[@]} -eq 0 ]; then
- whiptail --title "Error" --msgbox "No disks found to repair." 8 78
- log "No disks found for file system repair."
- return
- fi
- # Prepare radiolist options
- local choices=()
- for disk in "${disks[@]}"; do
- local size
- size=$(lsblk -d -o SIZE -n "/dev/$disk")
- choices+=("/dev/$disk" "Size: $size" OFF)
- done
- # Prompt user to select a disk
- local selected_disk
- selected_disk=$(whiptail --title "Repair File System" --radiolist \
- "Select a disk to repair its file system:" 20 80 10 \
- "${choices[@]}" 3>&1 1>&2 2>&3)
- # Check if user made a selection
- if [ -z "$selected_disk" ]; then
- log "File system repair cancelled by the user."
- return
- fi
- selected_disk=$(echo "$selected_disk" | tr -d '"')
- # Confirm the repair operation
- if ! confirm_action "Confirm Repair" "This will check and attempt to repair the file system on $selected_disk. It's recommended to close all other applications before proceeding. Continue?"; then
- log "File system repair cancelled by the user."
- return
- fi
- # Inform user to perform repair in terminal
- whiptail --title "Repair File System" --msgbox "Please perform the file system repair on $selected_disk manually in the terminal. Press OK to continue." 8 78
- log "Prompted user to perform file system repair manually."
- # Open a terminal window to run fsck (assuming gnome-terminal is available)
- if command -v gnome-terminal &>/dev/null; then
- gnome-terminal -- bash -c "sudo fsck -f $selected_disk; exec bash" &
- log "Opened gnome-terminal for fsck on $selected_disk."
- else
- # Fallback to executing fsck in the current terminal
- sudo fsck -f "$selected_disk" &>> "$LOG_FILE" || handle_error "fsck failed on $selected_disk."
- log "fsck executed on $selected_disk."
- fi
- whiptail --title "Repair File System" --msgbox "File system repair initiated for $selected_disk. Please monitor the terminal for progress." 8 78
- }
- # Function to clear system logs
- clear_system_logs() {
- if ! confirm_action "Clear System Logs" "Are you sure you want to clear all system logs? This action cannot be undone."; then
- log "Clear system logs cancelled by the user."
- return
- fi
- whiptail --title "Clearing System Logs" --infobox "Clearing system logs..." 8 78
- sudo journalctl --rotate &>> "$LOG_FILE" || handle_error "Failed to rotate journal logs."
- sudo journalctl --vacuum-time=1s &>> "$LOG_FILE" || handle_error "Failed to vacuum journal logs."
- whiptail --title "Clear System Logs" --msgbox "System logs have been cleared successfully." 8 78
- log "System logs cleared successfully."
- }
- # Function to reset a user's password
- reset_user_password() {
- # Prompt for the username
- local username
- username=$(whiptail --title "Reset User Password" --inputbox "Enter the username to reset the password for:" 8 60 3>&1 1>&2 2>&3)
- if [ $? -ne 0 ]; then
- log "Reset user password cancelled by the user."
- return
- fi
- if [ -z "$username" ]; then
- whiptail --title "Error" --msgbox "No username entered. Please provide a valid username." 8 78
- log "Reset user password failed: No username entered."
- return
- fi
- # Check if the user exists
- if ! id "$username" &>/dev/null; then
- whiptail --title "Error" --msgbox "User '$username' does not exist." 8 78
- log "Reset user password failed: User '$username' does not exist."
- return
- fi
- # Prompt user to enter a new password
- local new_password
- new_password=$(whiptail --title "Reset User Password" --passwordbox "Enter a new password for $username:" 10 60 3>&1 1>&2 2>&3)
- if [ $? -ne 0 ]; then
- log "Reset user password cancelled during password entry."
- return
- fi
- if [ -z "$new_password" ]; then
- whiptail --title "Error" --msgbox "No password entered. Please provide a valid password." 8 78
- log "Reset user password failed: No password entered."
- return
- fi
- # Reset the user's password
- echo "$username:$new_password" | sudo chpasswd &>> "$LOG_FILE" || handle_error "Failed to reset password for $username."
- whiptail --title "Reset User Password" --msgbox "Password for user '$username' has been reset successfully." 8 78
- log "Password for user '$username' reset successfully."
- }
- # Function for the final solution (extreme measures)
- the_final_solution() {
- # Warn the user about the consequences
- whiptail --title "Warning: The Final Solution" --msgbox "This action will remove everything, including plymouth, xorg, gnome (if installed), cinnamon (if installed), kde (if installed), gdm3, and any other configurations. All original configurations for certain tools will be lost. Proceed with caution and only use this as a last resort." 10 78
- # Ask for user confirmation
- if confirm_action "Confirm The Final Solution" "This action is non-reversible. Are you sure you want to proceed with the last resort fresh installation?"; then
- # Purge critical packages
- whiptail --title "Executing The Final Solution" --infobox "Purging critical packages..." 8 78
- sudo apt-get purge '^nvidia.*' '^plymouth.*' '^xorg.*' '^gnome.*' '^cinnamon.*' '^kde.*' '^gdm3.*' '^mate.*' '^xfce.*' '^ubuntu.*' -y &>> "$LOG_FILE" || handle_error "Failed to purge critical packages."
- # Reinstall essential packages
- whiptail --title "Reinstalling Essential Packages" --infobox "Reinstalling plymouth, xorg, and cinnamon..." 8 78
- sudo apt-get install plymouth xorg cinnamon -y &>> "$LOG_FILE" || handle_error "Failed to reinstall essential packages."
- whiptail --title "The Final Solution" --msgbox "The system has been reset to a fresh installation state. Please reboot your system." 8 78
- log "The Final Solution executed successfully."
- else
- log "The Final Solution cancelled by the user."
- main_menu
- fi
- }
- # Function to check installed desktop environments
- check_installed_desktops() {
- for DE in "${!DESKTOP_ENVS[@]}"; do
- # Initial assumption is that it's not installed
- DESKTOP_ENVS[$DE]="not installed"
- # Check if the package is installed
- if dpkg -s "${DESKTOP_ENVS[$DE]}" &>/dev/null; then
- DESKTOP_ENVS[$DE]="installed"
- else
- # Additional checks can be added here if necessary
- :
- fi
- done
- }
- # Function for Desktop Environment & Display menu
- desktop_environment_display_menu() {
- local choice
- choice=$(display_menu "Desktop Environment & Display" "Choose an action:" \
- "1" "Purge Xorg" \
- "2" "Reset X11" \
- "3" "LightDM Reset" \
- "4" "Make Wayland Default" \
- "5" "Desktop Environment Installer/Remover" \
- "6" "Startx Attempt" \
- "7" "Cinnamon Repair" \
- "8" "Back to Main Menu")
- case $choice in
- 1) purge_xorg ;;
- 2) reset_x11 ;;
- 3) lightdm_reset ;;
- 4) make_wayland_default ;;
- 5) desktop_environment_installer_remover ;;
- 6) startx_attempt ;;
- 7) cinnamon_repair ;;
- 8) main_menu ;;
- *) log "Invalid selection: $choice"; desktop_environment_display_menu ;;
- esac
- }
- # Function to install or remove desktop environments
- desktop_environment_installer_remover() {
- # Refresh the installation status
- check_installed_desktops
- # Prepare checklist options
- local choices=()
- for DE in "${!DESKTOP_ENVS[@]}"; do
- local status="${DESKTOP_ENVS[$DE]}"
- if [[ "$status" == "installed" ]]; then
- choices+=("$DE" "Installed" "ON")
- else
- choices+=("$DE" "Not Installed" "OFF")
- fi
- done
- # Prompt user to select desktop environments to install/remove
- local selected_des
- selected_des=$(whiptail --title "Desktop Environment Installer/Remover" --checklist \
- "Select desktop environments to install or remove:" 20 80 12 \
- "${choices[@]}" 3>&1 1>&2 2>&3)
- # Check if user made a selection
- if [ -z "$selected_des" ]; then
- log "No desktop environments selected for installation/removal."
- return
- fi
- # Convert selection to an array
- read -r -a selected_des <<< "$(echo "$selected_des" | tr -d '"')"
- # Iterate through selected desktop environments
- for DE in "${selected_des[@]}"; do
- if [[ "${DESKTOP_ENVS[$DE]}" == "installed" ]]; then
- # Prompt to remove the desktop environment
- if confirm_action "Remove $DE" "Do you want to remove the $DE desktop environment?"; then
- whiptail --title "Removing $DE" --infobox "Removing $DE desktop environment..." 8 78
- sudo apt-get purge "${DESKTOP_ENVS[$DE]}" -y &>> "$LOG_FILE" || handle_error "Failed to remove $DE."
- sudo apt-get autoremove -y &>> "$LOG_FILE" || handle_error "Failed to autoremove dependencies after removing $DE."
- whiptail --title "Remove $DE" --msgbox "$DE has been removed successfully." 8 78
- log "$DE desktop environment removed successfully."
- else
- log "Removal of $DE cancelled by the user."
- fi
- else
- # Prompt to install the desktop environment
- if confirm_action "Install $DE" "Do you want to install the $DE desktop environment?"; then
- whiptail --title "Installing $DE" --infobox "Installing $DE desktop environment..." 8 78
- sudo apt-get install "${DESKTOP_ENVS[$DE]}" -y &>> "$LOG_FILE" || handle_error "Failed to install $DE."
- whiptail --title "Install $DE" --msgbox "$DE desktop environment has been installed successfully." 8 78
- log "$DE desktop environment installed successfully."
- else
- log "Installation of $DE cancelled by the user."
- fi
- fi
- done
- # Refresh desktop environment status
- check_installed_desktops
- }
- # Function to attempt running startx
- startx_attempt() {
- whiptail --title "Startx Attempt" --msgbox "Attempting to start X server using startx. This will close all open applications." 8 78
- log "Attempting to start X server using startx."
- # Execute startx and log output
- startx &>> "$LOG_FILE" || handle_error "Failed to start X server with startx."
- whiptail --title "Startx Attempt" --msgbox "startx command executed. Check the log file for details." 8 78
- log "startx command executed."
- }
- # Function to repair Cinnamon desktop environment
- cinnamon_repair() {
- if ! dpkg -s cinnamon &>/dev/null && ! dpkg -s mint-meta-cinnamon &>/dev/null; then
- whiptail --title "Error" --msgbox "Cinnamon is not installed on your system." 8 78
- log "Cinnamon repair failed: Cinnamon is not installed."
- return
- fi
- whiptail --title "Cinnamon Repair" --infobox "Reinstalling Cinnamon packages..." 8 78
- sudo apt-get install --reinstall cinnamon mint-meta-cinnamon -y &>> "$LOG_FILE" || handle_error "Failed to reinstall Cinnamon packages."
- whiptail --title "Cinnamon Repair" --infobox "Resetting Cinnamon settings..." 8 78
- dconf reset -f /org/cinnamon/ &>> "$LOG_FILE" || handle_error "Failed to reset Cinnamon settings."
- whiptail --title "Cinnamon Repair" --msgbox "Cinnamon has been repaired and reset successfully." 8 78
- log "Cinnamon repaired and reset successfully."
- }
- # Function for System Tools & Utilities menu
- system_tools_utilities_menu() {
- local choice
- choice=$(display_menu "System Tools & Utilities" "Choose an action:" \
- "1" "System Info" \
- "2" "Repair File System" \
- "3" "Clear System Logs" \
- "4" "Reset User Password" \
- "5" "The Final Solution" \
- "6" "Back to Main Menu")
- case $choice in
- 1) system_info ;;
- 2) repair_file_system ;;
- 3) clear_system_logs ;;
- 4) reset_user_password ;;
- 5) the_final_solution ;;
- 6) main_menu ;;
- *) log "Invalid selection: $choice"; system_tools_utilities_menu ;;
- esac
- }
- # Function for the final solution (extreme measures)
- the_final_solution() {
- # Warn the user about the consequences
- whiptail --title "Warning: The Final Solution" --msgbox "This action will remove everything, including plymouth, xorg, gnome (if installed), cinnamon (if installed), kde (if installed), gdm3, and any other configurations. All original configurations for certain tools will be lost. Proceed with caution and only use this as a last resort." 10 78
- # Ask for user confirmation
- if confirm_action "Confirm The Final Solution" "This action is non-reversible. Are you sure you want to proceed with the last resort fresh installation?"; then
- # Purge critical packages
- whiptail --title "Executing The Final Solution" --infobox "Purging critical packages..." 8 78
- sudo apt-get purge '^nvidia.*' '^plymouth.*' '^xorg.*' '^gnome.*' '^cinnamon.*' '^kde.*' '^gdm3.*' '^mate.*' '^xfce.*' '^ubuntu.*' -y &>> "$LOG_FILE" || handle_error "Failed to purge critical packages."
- # Reinstall essential packages
- whiptail --title "Reinstalling Essential Packages" --infobox "Reinstalling plymouth, xorg, and cinnamon..." 8 78
- sudo apt-get install plymouth xorg cinnamon -y &>> "$LOG_FILE" || handle_error "Failed to reinstall essential packages."
- whiptail --title "The Final Solution" --msgbox "The system has been reset to a fresh installation state. Please reboot your system." 8 78
- log "The Final Solution executed successfully."
- else
- log "The Final Solution cancelled by the user."
- main_menu
- fi
- }
- # Function to check installed desktop environments
- check_installed_desktops() {
- for DE in "${!DESKTOP_ENVS[@]}"; do
- # Initial assumption is that it's not installed
- DESKTOP_ENVS[$DE]="not installed"
- # Check if the package is installed
- if dpkg -s "${DESKTOP_ENVS[$DE]}" &>/dev/null; then
- DESKTOP_ENVS[$DE]="installed"
- else
- # Additional checks can be added here if necessary
- :
- fi
- done
- }
- # Function for Boot & Disk Management menu
- boot_disk_management_menu() {
- local choice
- choice=$(display_menu "Boot & Disk Management" "Choose an action:" \
- "1" "Optimize Boot Sequence" \
- "2" "Fix Slow Boot Issues" \
- "3" "Restore Original Boot Sequence" \
- "4" "Manually Adjust Boot Sequence" \
- "5" "Remove Linux Kernel Versions" \
- "6" "Check Disk Health" \
- "7" "Back to Main Menu")
- case $choice in
- 1) optimize_boot_sequence ;;
- 2) fix_slow_boot ;;
- 3) restore_to_distro_default ;;
- 4) manually_adjust_boot_sequence ;;
- 5) remove_kernel_versions ;;
- 6) check_disk_health ;;
- 7) main_menu ;;
- *) log "Invalid selection: $choice"; boot_disk_management_menu ;;
- esac
- }
- # Function to optimize boot sequence
- optimize_boot_sequence() {
- whiptail --title "Optimizing Boot Sequence" --infobox "Backing up current unit files..." 8 78
- sudo systemctl list-unit-files --state=enabled > "$BACKUP_DIR/unit_files_$(date +%F_%T).backup" || handle_error "Failed to backup unit files."
- declare -A SERVICE_CATEGORIES=(
- [system]="systemd-* udev*"
- [filesystem]="*.mount"
- [drivers]="*-drivers.*"
- [user]="user@*.service"
- [user_defined]="httpd* mysqld* sshd*"
- )
- local services_to_process=()
- for category in "${!SERVICE_CATEGORIES[@]}"; do
- for pattern in ${SERVICE_CATEGORIES[$category]}; do
- while IFS= read -r line; do
- services_to_process+=("$line")
- done < <(systemctl list-unit-files --state=enabled | grep "$pattern" | awk '{print $1}')
- done
- done
- local total_services=${#services_to_process[@]}
- local counter=0
- local error_occurred=0
- {
- for service in "${services_to_process[@]}"; do
- let counter+=1
- if ! sudo systemctl disable "$service" &>> "$LOG_FILE"; then
- error_occurred=1
- echo "XXX"
- echo "Failed disabling $service ($counter of $total_services)"
- echo "XXX"
- echo $((counter * 50 / total_services))
- break
- fi
- echo "XXX"
- echo "Disabling $service ($counter of $total_services)"
- echo "XXX"
- echo $((counter * 50 / total_services))
- done
- if (( error_occurred == 0 )); then
- for service in "${services_to_process[@]}"; do
- let counter+=1
- if ! sudo systemctl enable "$service" &>> "$LOG_FILE"; then
- error_occurred=1
- echo "XXX"
- echo "Failed enabling $service ($counter of $total_services)"
- echo "XXX"
- echo $((counter * 50 / total_services + 50))
- break
- fi
- echo "XXX"
- echo "Enabling $service ($counter of $total_services)"
- echo "XXX"
- echo $((counter * 50 / total_services + 50))
- done
- fi
- } | whiptail --gauge "Optimizing boot sequence..." 20 70 0
- if (( error_occurred )); then
- whiptail --title "Error" --msgbox "An error occurred during the optimization process. Check the log file for details." 8 78
- log "Boot sequence optimization encountered errors."
- else
- whiptail --title "Optimize Boot Sequence" --msgbox "Boot sequence optimized successfully." 8 78
- log "Boot sequence optimized successfully."
- fi
- }
- # Function to fix slow boot issues
- fix_slow_boot() {
- whiptail --title "Fix Slow Boot Issues" --infobox "Backing up GRUB configuration..." 8 78
- sudo cp /etc/default/grub "$BACKUP_DIR/grub.bak_$(date +%F_%T)" || handle_error "Failed to backup GRUB configuration."
- # Disable plymouth-quit-wait.service
- sudo systemctl disable plymouth-quit-wait.service &>> "$LOG_FILE" || handle_error "Failed to disable plymouth-quit-wait.service."
- log "Disabled plymouth-quit-wait.service."
- # Reduce GRUB timeout
- sudo sed -i 's/^GRUB_TIMEOUT=.*/GRUB_TIMEOUT=5/' /etc/default/grub || handle_error "Failed to set GRUB_TIMEOUT."
- sudo update-grub &>> "$LOG_FILE" || handle_error "Failed to update GRUB."
- # Optimize systemd services
- local slow_units
- slow_units=$(systemd-analyze blame | head -n 5 | awk '{print $2}')
- for unit in $slow_units; do
- if confirm_action "Disable $unit" "Do you want to disable the slow service: $unit?"; then
- sudo systemctl disable "$unit" &>> "$LOG_FILE" || handle_error "Failed to disable $unit."
- log "Disabled slow service: $unit."
- fi
- done
- # Check for failed systemd units
- local failed_units
- failed_units=$(systemctl --failed --no-legend | grep ".service" | awk '{print $1}')
- if [ -n "$failed_units" ]; then
- whiptail --title "Failed Services" --msgbox "The following services have failed and may require manual intervention:\n$failed_units" 10 78
- log "Failed services detected: $failed_units."
- fi
- whiptail --title "Fix Slow Boot" --msgbox "Attempted to fix slow boot issues. Some changes might require a reboot." 8 78
- log "Attempted to fix slow boot issues."
- }
- # Function to restore boot sequence to distribution default
- restore_to_distro_default() {
- whiptail --title "Restore Boot Sequence" --infobox "Restoring boot sequence to distribution defaults..." 8 78
- sudo systemctl preset-all &>> "$LOG_FILE" || handle_error "Failed to preset all systemd unit files."
- sudo update-grub &>> "$LOG_FILE" || handle_error "Failed to update GRUB."
- whiptail --title "Restore Boot Sequence" --msgbox "Boot sequence has been restored to distribution defaults successfully." 8 78
- log "Boot sequence restored to distribution defaults."
- }
- # Function to manually adjust boot sequence
- manually_adjust_boot_sequence() {
- # List all enabled services
- local services
- services=$(systemctl list-unit-files --state=enabled | awk '{print $1}' | grep '.service')
- # Prepare checklist options
- local choices=()
- for svc in $services; do
- choices+=("$svc" "" "OFF")
- done
- # Prompt user to select services to enable/disable
- local selected_services
- selected_services=$(whiptail --title "Adjust Boot Sequence" --checklist \
- "Select services to toggle (use space to select):" 20 100 15 \
- "${choices[@]}" 3>&1 1>&2 2>&3)
- # Check if user made a selection
- if [ -z "$selected_services" ]; then
- log "No services selected for manual adjustment."
- return
- fi
- # Convert selection to an array
- read -r -a selected_services <<< "$(echo "$selected_services" | tr -d '"')"
- # Iterate through selected services
- for svc in "${selected_services[@]}"; do
- if systemctl is-enabled --quiet "$svc"; then
- if confirm_action "Disable $svc" "Do you want to disable the service: $svc?"; then
- sudo systemctl disable "$svc" &>> "$LOG_FILE" || handle_error "Failed to disable $svc."
- log "Disabled service: $svc."
- fi
- else
- if confirm_action "Enable $svc" "Do you want to enable the service: $svc?"; then
- sudo systemctl enable "$svc" &>> "$LOG_FILE" || handle_error "Failed to enable $svc."
- log "Enabled service: $svc."
- fi
- fi
- done
- whiptail --title "Adjust Boot Sequence" --msgbox "Boot sequence has been manually adjusted." 8 78
- log "Boot sequence manually adjusted."
- }
- # Function to remove old Linux kernel versions
- remove_kernel_versions() {
- # Get current kernel version
- local current_kernel
- current_kernel=$(uname -r)
- # List all installed kernel packages excluding the current one
- local kernels
- kernels=$(dpkg --list | grep 'linux-image-[0-9]' | awk '{print $2}' | grep -v "$current_kernel")
- if [ -z "$kernels" ]; then
- whiptail --title "Remove Kernel" --msgbox "No additional kernels found to remove." 8 78
- log "No additional kernels found for removal."
- return
- fi
- # Prepare checklist options
- local choices=()
- for kernel in $kernels; do
- choices+=("$kernel" "Installed" "OFF")
- done
- # Prompt user to select kernels to remove
- local selected_kernels
- selected_kernels=$(whiptail --title "Remove Kernel Versions" --checklist \
- "Select kernels to uninstall:" 20 100 15 \
- "${choices[@]}" 3>&1 1>&2 2>&3)
- # Check if user made a selection
- if [ -z "$selected_kernels" ]; then
- log "No kernels selected for removal."
- return
- fi
- # Convert selection to an array
- read -r -a selected_kernels <<< "$(echo "$selected_kernels" | tr -d '"')"
- # Iterate through selected kernels and remove them
- for kernel in "${selected_kernels[@]}"; do
- if confirm_action "Remove $kernel" "Are you sure you want to remove $kernel?"; then
- whiptail --title "Removing $kernel" --infobox "Removing $kernel..." 8 78
- sudo apt-get purge "$kernel" -y &>> "$LOG_FILE" || handle_error "Failed to remove $kernel."
- sudo apt-get autoremove -y &>> "$LOG_FILE" || handle_error "Failed to autoremove dependencies after removing $kernel."
- log "Removed kernel: $kernel."
- fi
- done
- # Update GRUB after kernel removal
- sudo update-grub &>> "$LOG_FILE" || handle_error "Failed to update GRUB after kernel removal."
- whiptail --title "Remove Kernel Versions" --msgbox "Selected kernels have been removed successfully. Please reboot your system." 8 78
- log "Selected kernels removed successfully."
- }
- # Function to check disk health using smartctl
- check_disk_health() {
- # Ensure smartmontools is installed
- if ! dpkg -s smartmontools &>/dev/null; then
- if confirm_action "Install smartmontools" "smartmontools is not installed. Do you want to install it now?"; then
- sudo apt-get update && sudo apt-get install smartmontools -y &>> "$LOG_FILE" || handle_error "Failed to install smartmontools."
- log "smartmontools installed successfully."
- else
- log "smartmontools not installed. Cannot check disk health."
- whiptail --title "Error" --msgbox "smartmontools is required to check disk health." 8 78
- return
- fi
- fi
- # List available disks excluding loop devices
- local disks=($(lsblk -d -o NAME,TYPE | awk '$2=="disk"{print $1}'))
- if [ ${#disks[@]} -eq 0 ]; then
- whiptail --title "Error" --msgbox "No disks found to check." 8 78
- log "No disks found for health check."
- return
- fi
- # Prepare radiolist options
- local choices=()
- for disk in "${disks[@]}"; do
- local size
- size=$(lsblk -d -o SIZE -n "/dev/$disk")
- choices+=("/dev/$disk" "Size: $size" OFF)
- done
- # Prompt user to select a disk
- local selected_disk
- selected_disk=$(whiptail --title "Select Disk for Health Check" --radiolist \
- "Choose a disk to check its health:" 20 78 10 \
- "${choices[@]}" 3>&1 1>&2 2>&3)
- # Check if user made a selection
- if [ -z "$selected_disk" ]; then
- log "Disk health check cancelled by the user."
- return
- fi
- selected_disk=$(echo "$selected_disk" | tr -d '"')
- # Run SMART health check
- whiptail --title "Disk Health Check" --infobox "Running SMART health check on $selected_disk..." 8 78
- local health_report
- health_report=$(sudo smartctl -H "$selected_disk" 2>> "$LOG_FILE") || handle_error "Failed to retrieve SMART health report for $selected_disk."
- # Parse health status
- local health_status
- health_status=$(echo "$health_report" | grep -oP 'SMART overall-health self-assessment test result: \K.*')
- # Interpret the health status
- local message=""
- if [[ "$health_status" =~ ^(PASSED|OK)$ ]]; then
- message="✅ Your disk ($selected_disk) is in good health."
- else
- message="⚠️ Warning: Potential issues detected with disk ($selected_disk). Please investigate further."
- fi
- # Display the result
- whiptail --title "Disk Health Check" --msgbox "$message\n\n$health_report" 20 78
- log "Disk health check for $selected_disk: $health_status."
- }
- # Function to install or remove desktop environments
- desktop_environment_installer_remover() {
- # Refresh the installation status
- check_installed_desktops
- # Prepare checklist options
- local choices=()
- for DE in "${!DESKTOP_ENVS[@]}"; do
- local status="${DESKTOP_ENVS[$DE]}"
- if [[ "$status" == "installed" ]]; then
- choices+=("$DE" "Installed" "ON")
- else
- choices+=("$DE" "Not Installed" "OFF")
- fi
- done
- # Prompt user to select desktop environments to install/remove
- local selected_des
- selected_des=$(whiptail --title "Desktop Environment Installer/Remover" --checklist \
- "Select desktop environments to install or remove:" 20 80 12 \
- "${choices[@]}" 3>&1 1>&2 2>&3)
- # Check if user made a selection
- if [ -z "$selected_des" ]; then
- log "No desktop environments selected for installation/removal."
- return
- fi
- # Convert selection to an array
- read -r -a selected_des <<< "$(echo "$selected_des" | tr -d '"')"
- # Iterate through selected desktop environments
- for DE in "${selected_des[@]}"; do
- if [[ "${DESKTOP_ENVS[$DE]}" == "installed" ]]; then
- # Prompt to remove the desktop environment
- if confirm_action "Remove $DE" "Do you want to remove the $DE desktop environment?"; then
- whiptail --title "Removing $DE" --infobox "Removing $DE desktop environment..." 8 78
- sudo apt-get purge "${DESKTOP_ENVS[$DE]}" -y &>> "$LOG_FILE" || handle_error "Failed to remove $DE."
- sudo apt-get autoremove -y &>> "$LOG_FILE" || handle_error "Failed to autoremove dependencies after removing $DE."
- whiptail --title "Remove $DE" --msgbox "$DE has been removed successfully." 8 78
- log "$DE desktop environment removed successfully."
- else
- log "Removal of $DE cancelled by the user."
- fi
- else
- # Prompt to install the desktop environment
- if confirm_action "Install $DE" "Do you want to install the $DE desktop environment?"; then
- whiptail --title "Installing $DE" --infobox "Installing $DE desktop environment..." 8 78
- sudo apt-get install "${DESKTOP_ENVS[$DE]}" -y &>> "$LOG_FILE" || handle_error "Failed to install $DE."
- whiptail --title "Install $DE" --msgbox "$DE desktop environment has been installed successfully." 8 78
- log "$DE desktop environment installed successfully."
- else
- log "Installation of $DE cancelled by the user."
- fi
- fi
- done
- # Refresh desktop environment status
- check_installed_desktops
- }
- # Function to attempt running startx
- startx_attempt() {
- whiptail --title "Startx Attempt" --msgbox "Attempting to start X server using startx. This will close all open applications." 8 78
- log "Attempting to start X server using startx."
- # Execute startx and log output
- startx &>> "$LOG_FILE" || handle_error "Failed to start X server with startx."
- whiptail --title "Startx Attempt" --msgbox "startx command executed. Check the log file for details." 8 78
- log "startx command executed."
- }
- # Function to repair Cinnamon desktop environment
- cinnamon_repair() {
- if ! dpkg -s cinnamon &>/dev/null && ! dpkg -s mint-meta-cinnamon &>/dev/null; then
- whiptail --title "Error" --msgbox "Cinnamon is not installed on your system." 8 78
- log "Cinnamon repair failed: Cinnamon is not installed."
- return
- fi
- whiptail --title "Cinnamon Repair" --infobox "Reinstalling Cinnamon packages..." 8 78
- sudo apt-get install --reinstall cinnamon mint-meta-cinnamon -y &>> "$LOG_FILE" || handle_error "Failed to reinstall Cinnamon packages."
- whiptail --title "Cinnamon Repair" --infobox "Resetting Cinnamon settings..." 8 78
- dconf reset -f /org/cinnamon/ &>> "$LOG_FILE" || handle_error "Failed to reset Cinnamon settings."
- whiptail --title "Cinnamon Repair" --msgbox "Cinnamon has been repaired and reset successfully." 8 78
- log "Cinnamon repaired and reset successfully."
- }
- # Function to check installed desktop environments
- check_installed_desktops() {
- for DE in "${!DESKTOP_ENVS[@]}"; do
- # Initial assumption is that it's not installed
- DESKTOP_ENVS[$DE]="not installed"
- # Check if the package is installed
- if dpkg -s "${DESKTOP_ENVS[$DE]}" &>/dev/null; then
- DESKTOP_ENVS[$DE]="installed"
- else
- # Additional checks can be added here if necessary
- :
- fi
- done
- }
- # Function to ensure smartmontools is installed
- ensure_smartmontools_installed() {
- if ! dpkg -s smartmontools &>/dev/null; then
- if confirm_action "Install smartmontools" "smartmontools is not installed. Do you want to install it now?"; then
- sudo apt-get update && sudo apt-get install smartmontools -y &>> "$LOG_FILE" || handle_error "Failed to install smartmontools."
- log "smartmontools installed successfully."
- else
- log "smartmontools not installed."
- fi
- fi
- }
- # Main function to start the script
- main() {
- ask_for_sudo
- ensure_smartmontools_installed
- check_installed_desktops
- while true; do
- main_menu
- done
- }
- # Start the script
- main
Add Comment
Please, Sign In to add comment