System-Wide Refactor & Critical Fixes

- Resolved NVIDIA driver management issues by expanding package detection patterns (including nvidia-open and nvidia-kernel-open-dkms), enhancing purge process to ensure clean uninstallation of v590/595 drivers, and adding conditional skip for manage menu when no driver is installed.  
- Enhanced Firefox variant selection in internet.sh using exact token matching (grep -qx) instead of substring search to prevent incorrect removal or unintended ESR/Firefox conflicts. 
- New XFCE install option with 4 options
- Restructured Desktop Environment into two-level menu system with dispatcher and Xfce sub-menu for scalability, enabling future additions like GNOME/KDE without disrupting existing flows.  
- Added Polkit rules in desktop_display.sh to grant suspend permissions without password prompts on laptops, including idempotent group (backlight) creation and user membership management with || true fallbacks.  
- Enforced LC_ALL=C LANGUAGE=C environment variables for all dpkg-reconfigure commands across System Preferences and utils.sh to ensure native dialogues run consistently in English.  
- Fixed kernel backports menu option availability to only appear on Debian 13, preventing errors on Debian 12 where backports repositories are EOL.  
- Improved ZRAM module initialization sequence by ensuring swapoff and zram module removal occur before writing new configuration files to prevent race conditions during system setup.
This commit is contained in:
stornic56
2026-08-17 23:50:39 -05:00
committed by GitHub
parent dbd2dfca37
commit 0e24e8f9ae
10 changed files with 413 additions and 40 deletions
+26 -22
View File
@@ -32,6 +32,8 @@ source "${MODULES_DIR}/repos.sh"
[ -f "${MODULES_DIR}/rescue.sh" ] && source "${MODULES_DIR}/rescue.sh"
[ -f "${MODULES_DIR}/swap.sh" ] && source "${MODULES_DIR}/swap.sh"
[ -f "${MODULES_DIR}/desktop_display.sh" ] && source "${MODULES_DIR}/desktop_display.sh"
[ -f "${MODULES_DIR}/system/system_prefs.sh" ] && source "${MODULES_DIR}/system/system_prefs.sh"
[ -f "${MODULES_DIR}/system/audio.sh" ] && source "${MODULES_DIR}/system/audio.sh"
# ── Bullseye-specific modules (loaded only on Debian 11) ──
if [ -d "${MODULES_DIR}/bullseye" ]; then
@@ -60,24 +62,26 @@ main_menu() {
$TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
"1" "System Information" \
"2" "User Privileges & Feedback" \
"3" "Configure Repositories" \
"4" "Firmware, Wireless & Bluetooth" \
"5" "Graphics Drivers & Mesa Stack" \
"6" "Kernel" \
"7" "Gaming Setup" \
"8" "ZRAM" \
"9" "Swap Management" \
"10" "Install Programs and Software" \
"11" "Boot Rescue + GRUB" \
"12" "Desktop & Display" \
"13" "Exit")
"3" "System Preferences" \
"4" "Configure Repositories" \
"5" "Firmware, Wireless & Bluetooth" \
"6" "Graphics Drivers & Mesa Stack" \
"7" "Kernel" \
"8" "Gaming Setup" \
"9" "ZRAM" \
"10" "Swap Management" \
"11" "Install Programs and Software" \
"12" "Boot Rescue + GRUB" \
"13" "Desktop & Display" \
"14" "Exit")
clear
case "$choice" in
1) _show_sysinfo ;;
2) config_sudo || true ;;
3)
3) _system_preferences_menu ;;
4)
if [ "$DEBIAN_VERSION" = "11" ] && type configure_repos_bullseye &>/dev/null; then
configure_repos_bullseye || true
else
@@ -85,14 +89,14 @@ main_menu() {
fi
STATE_REFRESHED=true
;;
4)
5)
if [ "$DEBIAN_VERSION" = "11" ] && type install_firmware_bullseye &>/dev/null; then
install_firmware_bullseye || true
else
install_firmware || true
fi
;;
5)
6)
local gpu_sub
gpu_sub=$(_menu "Graphics Drivers" "" 12 50 2 \
"1" "Radeon/Intel Mesa" \
@@ -105,8 +109,8 @@ main_menu() {
esac
STATE_REFRESHED=true
;;
6) show_kernel_menu || true ;;
7)
7) show_kernel_menu || true ;;
8)
if [ "$DEBIAN_VERSION" = "11" ] && type install_gaming_bullseye &>/dev/null; then
install_gaming_bullseye || true
else
@@ -114,18 +118,18 @@ main_menu() {
fi
STATE_REFRESHED=true
;;
8) zram_menu || true ;;
9) manage_swap || true; STATE_REFRESHED=true ;;
10)
9) zram_menu || true ;;
10) manage_swap || true; STATE_REFRESHED=true ;;
11)
if [ "$DEBIAN_VERSION" = "11" ] && type install_extras_bullseye &>/dev/null; then
install_extras_bullseye || true
else
install_extras || true
fi
;;
11) rescue_boot || true ;;
12) manage_desktop_display || true ;;
13) echo "Exiting."; exit 0 ;;
12) rescue_boot || true ;;
13) manage_desktop_display || true ;;
14) echo "Exiting."; exit 0 ;;
esac
if $STATE_REFRESHED; then
refresh_system_state
+118 -1
View File
@@ -11,13 +11,130 @@ manage_desktop_display() {
[ -z "$choice" ] && break
clear
case "$choice" in
1) _msg "Coming Soon" "Desktop Environment management will be available in a future update." 10 60 ;;
1) desktop_environment_menu ;;
2) display_manager_menu ;;
3) break ;;
esac
done
}
desktop_environment_menu() {
while true; do
local -a env_items=()
env_items+=("1" "XFCE")
env_items+=("2" "Back")
# Future desktop environments: add "2" "GNOME", "3" "KDE", ... here
# and a matching case below calling its own menu (e.g. gnome_menu).
local choice
choice=$(_menu "Desktop Environment" \
"Select a desktop environment:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
"${env_items[@]}")
[ -z "$choice" ] && break
clear
case "$choice" in
1) xfce_menu ;;
2) break ;;
esac
done
}
xfce_menu() {
while true; do
local -a xf_items=()
xf_items+=("1" "XFCE (Full Meta Package)")
xf_items+=("2" "XFCE (Minimal Core)")
[ "$DEBIAN_VERSION" = "13" ] && xf_items+=("3" "XFCE Wayland (Experimental — labwc)")
xf_items+=("4" "XFCE Custom (Choose packages)")
xf_items+=("5" "Back")
local choice
choice=$(_menu "XFCE" \
"Select an option:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
"${xf_items[@]}")
[ -z "$choice" ] && break
clear
case "$choice" in
1) _install_xfce_full ;;
2) _install_xfce_minimal ;;
3) _install_xfce_wayland ;;
4) _install_xfce_custom ;;
5) break ;;
esac
done
}
_install_xfce_full() {
_run_cmd "XFCE Full" "sudo apt install -y xfce4 xfce4-goodies xfce4-power-manager" \
"Installing XFCE (Full Meta Package)..."
_xfce_polkit_rules
}
_install_xfce_minimal() {
_run_cmd "XFCE Minimal" "sudo apt install -y xfce4" \
"Installing XFCE (Minimal Core)..."
_xfce_polkit_rules
}
_install_xfce_wayland() {
_run_cmd "XFCE Wayland" "sudo apt install -y xfce4 labwc" \
"Installing XFCE + labwc (Wayland, experimental)..."
_msg "XFCE Wayland" "labwc is EXPERIMENTAL on XFCE 4.20.\n\nAfter reboot, select the Wayland session\nfrom the login screen." 12 65
_xfce_polkit_rules
}
_install_xfce_custom() {
local -a items=()
for pkg in thunar xfdesktop4 xfwm4 xfce4-panel xfce4-terminal \
xfce4-screenshooter ristretto mousepad xfce4-session \
xfce4-settings xfce4-power-manager; do
items+=("$pkg" "$pkg" "$(_state "$pkg")")
done
local choices
choices=$(_checklist "XFCE Custom" \
"Select the XFCE packages to install:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
"${items[@]}")
[ -z "$choices" ] && return
local cleaned
cleaned=$(echo "$choices" | tr -d '"')
[ -z "$cleaned" ] && return
_run_cmd "XFCE Custom" "sudo apt install -y $cleaned" \
"Installing selected XFCE packages..."
_xfce_polkit_rules
}
_xfce_polkit_rules() {
is_installed xfce4-power-manager || return 0
local rules_dir="/etc/polkit-1/rules.d"
sudo mkdir -p "$rules_dir"
cat <<'EOF' | sudo tee "$rules_dir/85-suspend.rules" >/dev/null
polkit.addRule(function(action, subject) {
if (action.id == "org.freedesktop.login1.suspend" &&
subject.isInGroup("users")) {
return polkit.Result.YES;
}
});
EOF
cat <<'EOF' | sudo tee "$rules_dir/89-backlight.rules" >/dev/null
polkit.addRule(function(action, subject) {
if (action.id == "org.freedesktop.upower.backlight" &&
subject.isInGroup("backlight")) {
return polkit.Result.YES;
}
});
EOF
if ! getent group backlight >/dev/null 2>&1; then
sudo groupadd --system backlight || true
fi
local de_user="${SUDO_USER:-$USER}"
if [ -n "$de_user" ] && ! id -nG "$de_user" 2>/dev/null | grep -qw backlight; then
sudo usermod -aG backlight "$de_user" || true
fi
sudo systemctl restart polkit.service 2>/dev/null || true
echo -e "${GREEN}Polkit rules installed (suspend + backlight). User '${de_user}' added to 'backlight' group.${NC}"
}
display_manager_menu() {
while true; do
local -a dm_items=()
+2 -4
View File
@@ -43,8 +43,7 @@ install_extras() {
"11" "Office & Productivity" \
"12" "System Tools" \
"13" "Fetch / System Info" \
"14" "Audio & Sound" \
"15" "Back to main menu")
"14" "Back to main menu")
[ -z "$cat_choice" ] && return
clear
@@ -64,8 +63,7 @@ install_extras() {
11) _cat_office ;;
12) _cat_general ;;
13) _cat_fetch ;;
14) _cat_audio ;;
15) return ;;
14) return ;;
esac
clear
done
+18 -3
View File
@@ -183,9 +183,24 @@ _cat_internet() {
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
if echo "$cleaned" | grep -q "firefox" && echo "$cleaned" | grep -q "firefox-esr"; then
_msg "Firefox" "You selected both Firefox (Mozilla) and Firefox ESR.\nPlease choose only one Firefox variant." 10 60
return
local has_firefox=false
local has_firefox_esr=false
for _p in $cleaned; do
[ "$_p" = "firefox" ] && has_firefox=true
[ "$_p" = "firefox-esr" ] && has_firefox_esr=true
done
if $has_firefox && $has_firefox_esr; then
local fchoice
fchoice=$(_menu "Firefox" "You selected both Firefox (Mozilla) and Firefox ESR.\nWhat do you want to do?" 12 60 3 \
"mozilla" "Remove Firefox ESR — keep Firefox" \
"esr" "Remove Firefox — keep Firefox ESR" \
"both" "Keep both variants")
[ -z "$fchoice" ] && return
case "$fchoice" in
mozilla) cleaned=$(printf '%s\n' $cleaned | grep -vx "firefox-esr" | tr '\n' ' ') ;;
esr) cleaned=$(printf '%s\n' $cleaned | grep -vx "firefox" | tr '\n' ' ') ;;
esac
fi
for pkg in $cleaned; do
+14 -5
View File
@@ -191,12 +191,19 @@ _install_nvidia_stack() {
NVIDIA_DRIVER_MODE=""
if ! _nvidia_manage_menu; then
return
if _nvidia_driver_installed; then
if ! _nvidia_manage_menu; then
return
fi
fi
if [ "$DEBIAN_VERSION" = "11" ]; then
install_nvidia_bullseye
if type install_nvidia_bullseye &>/dev/null; then
install_nvidia_bullseye
else
_msg "NVIDIA — Bullseye" "The Bullseye NVIDIA module is not available.\n\nNo NVIDIA driver was installed." 10 60
NVIDIA_DRIVER_MODE=""
fi
else
if ! _show_nvidia_version_menu; then
@@ -230,7 +237,9 @@ _install_nvidia_stack() {
NVIDIA_DRIVER_MODE=""
;;
blackwell)
_install_nvidia_cuda_repo
_msg "NVIDIA — Blackwell (v550)" \
"Your Blackwell GPU is NOT supported by the official\nDebian v550 driver.\n\nPlease select v590 or v595 (NVIDIA CUDA Repo)\nin the driver menu." 14 65
NVIDIA_DRIVER_MODE=""
;;
maxwell|pascal|volta)
if [ "$(is_backports_kernel)" = "true" ]; then
@@ -253,7 +262,7 @@ Forcing the stable driver path." 14 70
_install_nvidia_standard
fi
;;
turing|ampere|ada|blackwell)
turing|ampere|ada)
_install_nvidia_standard
;;
*)
+6 -2
View File
@@ -1,6 +1,10 @@
#!/usr/bin/env bash
# nvidia_manage.sh — NVIDIA management menu: install/change or remove
_nvidia_driver_installed() {
dpkg -l 2>/dev/null | grep -qE "^ii (nvidia-driver|nvidia-tesla-470-driver|nvidia-open|nvidia-kernel-dkms|nvidia-kernel-open-dkms|nvidia-open-kernel-dkms)"
}
_nvidia_manage_menu() {
local choice
choice=$(_menu "NVIDIA Driver" "Manage NVIDIA Driver" 12 70 4 \
@@ -22,7 +26,7 @@ _nvidia_manage_menu() {
}
_nvidia_remove() {
if ! dpkg -l 2>/dev/null | grep -qE "^ii (nvidia-driver|nvidia-tesla-470-driver|nvidia-open-kernel-dkms|nvidia-kernel-dkms)"; then
if ! _nvidia_driver_installed; then
echo -e "${YELLOW}NVIDIA driver is not installed on this system.${NC}"
return 0
fi
@@ -33,7 +37,7 @@ _nvidia_remove() {
fi
echo "Removing NVIDIA driver packages..."
sudo apt purge -y nvidia-driver nvidia-kernel-dkms nvidia-open-kernel-dkms nvidia-tesla-470-driver nvidia-settings nvidia-vaapi-driver firmware-nvidia-gsp mesa-vdpau-drivers || true
sudo apt purge -y nvidia-driver nvidia-kernel-dkms nvidia-open-kernel-dkms nvidia-open nvidia-kernel-open-dkms nvidia-tesla-470-driver nvidia-settings nvidia-vaapi-driver firmware-nvidia-gsp mesa-vdpau-drivers nvidia-driver-pinning-* || true
echo "Cleaning up dependencies..."
sudo apt autoremove --purge -y || true
+1 -1
View File
@@ -4,7 +4,7 @@
show_kernel_menu() {
while true; do
local items=("stable" "Install linux-image-amd64")
[ "$DEBIAN_VERSION" != "11" ] && items+=("backports" "Install from backports")
[ "$DEBIAN_VERSION" = "13" ] && items+=("backports" "Install from backports")
items+=("rt" "Install linux-image-rt-amd64 (Preempt-RT)")
items+=("cloud" "Install linux-image-cloud-amd64")
items+=("back" "Return to main menu")
+185
View File
@@ -0,0 +1,185 @@
#!/usr/bin/env bash
# audio.sh — Audio & Sound (PipeWire, ALSA, PulseAudio tools)
_prefs_audio_menu() {
local headless=false
_is_headless && headless=true
local -a items=()
local pw_label="PipeWire Audio Stack (Bluetooth Hi-Res)"
local pw_state; pw_state=$(_state "pipewire-audio")
items+=(
"pipewire-audio" "$pw_label" "$pw_state"
)
local alsa_state; alsa_state=$(_state "alsa-utils")
items+=(
"alsa-utils" "ALSA Utilities (alsa-utils, alsa-ucm-conf)" "$alsa_state"
)
if ! $headless; then
local pavu_state; pavu_state=$(_state "pavucontrol")
items+=(
"pavucontrol" "Volume Control GUI (pavucontrol)" "$pavu_state"
)
fi
local pulsemixer_state; pulsemixer_state=$(_state "pulsemixer")
local playerctl_state; playerctl_state=$(_state "playerctl")
items+=(
"pulsemixer" "Terminal audio mixer (pulsemixer)" "$pulsemixer_state"
"playerctl" "Multimedia key controller (playerctl)" "$playerctl_state"
)
local item_count=${#items[@]}
local lista_alto=$((item_count > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count))
local choices
choices=$(_checklist "Audio & Sound" "Check [*] the packages you want installed.\n" \
$TUI_ALTO $TUI_ANCHO $lista_alto "${items[@]}")
clear
[ -z "$choices" ] && return
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
for pkg in $cleaned; do
case $pkg in
pipewire-audio) _install_pipewire_standard ;;
alsa-utils)
if ! is_installed "alsa-utils"; then
_run_install "alsa-utils alsa-ucm-conf"
else
echo "alsa-utils already installed."
fi
;;
pavucontrol)
if ! is_installed "pavucontrol"; then
_run_install "pavucontrol"
else
echo "pavucontrol already installed."
fi
;;
pulsemixer)
if ! is_installed "pulsemixer"; then
_run_install "pulsemixer"
else
echo "pulsemixer already installed."
fi
;;
playerctl)
if ! is_installed "playerctl"; then
_run_install "playerctl"
else
echo "playerctl already installed."
fi
;;
esac
done
echo -e "${GREEN}Audio & Sound setup complete.${NC}"
}
_install_pipewire_standard() {
local bt_pkgs="libldacbt-abr2 libldacbt-enc2 libopenaptx0 libspa-0.2-bluetooth"
if apt-cache show libfdk-aac2t64 &>/dev/null; then
bt_pkgs+=" libfdk-aac2t64"
elif apt-cache show libfdk-aac2 &>/dev/null; then
bt_pkgs+=" libfdk-aac2"
fi
# ── Resolve versions (needed for both installed and not-installed branches) ──
local stable_ver=""
stable_ver=$(apt-cache policy pipewire-audio 2>/dev/null | awk 'NR==3 {print $2; exit}') || true
local bpo_ver=""
if [ "$DEBIAN_VERSION" = "13" ] && [ "$(is_backports_enabled)" = "true" ]; then
bpo_ver=$(apt-cache madison pipewire-audio 2>/dev/null | \
grep "${DEBIAN_CODENAME}-backports" | awk '{print $3}' | head -1) || true
fi
local pkg_check="pipewire-audio"
[ "$DEBIAN_VERSION" = "11" ] && pkg_check="pipewire"
# ── Already installed branch ──
if is_installed "$pkg_check"; then
if [ -n "$bpo_ver" ]; then
local current_ver
current_ver=$(dpkg -l "$pkg_check" 2>/dev/null | awk '/^ii/{print $3}') || true
if _confirm "PipeWire" \
"PipeWire ${current_ver:+v${current_ver} }already installed.\n\nUpgrade to backports version v${bpo_ver}?"; then
echo "Upgrading PipeWire Audio Stack..."
echo "-> Target version: v${bpo_ver} (from ${DEBIAN_CODENAME}-backports)"
echo "-> Including Bluetooth Hi-Res codecs (LDAC, aptX, AAC)"
_run_cmd "PipeWire" \
"sudo apt install -y --reinstall -t ${DEBIAN_CODENAME}-backports pipewire-audio $bt_pkgs" \
"Upgrading PipeWire from backports..."
if [ "$DEBIAN_VERSION" != "11" ]; then
echo "Restarting PipeWire services..."
systemctl --user restart wireplumber pipewire pipewire-pulse 2>/dev/null || true
echo -e "${GREEN}PipeWire services restarted.${NC}"
fi
return
fi
fi
echo "$pkg_check already installed."
return
fi
# ── Confirm dialog ──
local apt_target="" pw_ver="" pw_src=""
if [ -n "$bpo_ver" ]; then
local msg="Backports repository is enabled.\n\n"
msg+="Available versions:\n"
msg+=" - Stable: v${stable_ver:-unknown}\n"
msg+=" - Backports: v${bpo_ver}\n\n"
msg+="Install from Backports (Recommended for newer hardware)\nor from Stable (more conservative)?"
if _confirm_custom "PipeWire Install" "$msg" "Backports" "Stable" 14 70; then
apt_target="-t ${DEBIAN_CODENAME}-backports"
pw_ver="$bpo_ver"
pw_src="from ${DEBIAN_CODENAME}-backports"
else
pw_ver="$stable_ver"
fi
else
local msg="PipeWire Audio Stack (v${stable_ver:-unknown})\n"
msg+="will be installed along with Bluetooth Hi-Res\n"
msg+="codecs (LDAC, aptX, AAC).\n\n"
msg+="Continue with installation?"
if ! _confirm "PipeWire Install" "$msg" 12 65; then
echo "PipeWire installation cancelled."
return
fi
pw_ver="$stable_ver"
fi
echo "Installing PipeWire Audio Stack..."
echo "-> Detected version: ${pw_ver:-unknown} ${pw_src:+($pw_src)}"
echo "-> Including Bluetooth Hi-Res codecs (LDAC, aptX, AAC)"
case "$DEBIAN_VERSION" in
11)
_run_cmd "PipeWire" \
"sudo apt install -y pipewire libspa-0.2-bluetooth pipewire-alsa libspa-0.2-jack $bt_pkgs" \
"Installing PipeWire (Bullseye basic mode)..."
echo -e "${GREEN}PipeWire installed (Bullseye basic mode).${NC}"
;;
12)
_run_cmd "PipeWire" \
"sudo apt install -y pipewire-audio $bt_pkgs" \
"Installing pipewire-audio meta-package (Bookworm)..."
echo -e "${GREEN}PipeWire audio stack installed.${NC}"
;;
13)
_run_cmd "PipeWire" \
"sudo apt install -y $apt_target pipewire-audio $bt_pkgs" \
"Installing pipewire-audio meta-package (Trixie)..."
echo -e "${GREEN}PipeWire audio stack installed.${NC}"
;;
esac
if [ "$DEBIAN_VERSION" != "11" ]; then
echo "Restarting PipeWire services..."
systemctl --user restart wireplumber pipewire pipewire-pulse 2>/dev/null || true
echo -e "${GREEN}PipeWire services restarted.${NC}"
fi
}
+41
View File
@@ -0,0 +1,41 @@
#!/usr/bin/env bash
# system_prefs.sh — System Preferences: time, locale, keyboard, audio
_prefs_date_time() {
echo -e "${YELLOW}Current system date/time:${NC} $(date '+%Y-%m-%d %H:%M')"
echo -e "${YELLOW}Timezone:${NC} $(timedatectl show -p Timezone --value 2>/dev/null || echo unknown)"
if _confirm "Timezone" "Change the system timezone (dpkg-reconfigure tzdata)?"; then
sudo env LC_ALL=C LANGUAGE=C dpkg-reconfigure tzdata || true
echo -e "${GREEN}Timezone: $(timedatectl show -p Timezone --value 2>/dev/null)${NC}"
fi
_ensure_time_synced
}
_prefs_locale_keyboard() {
sudo env LC_ALL=C LANGUAGE=C dpkg-reconfigure locales || true
sudo env LC_ALL=C LANGUAGE=C dpkg-reconfigure keyboard-configuration || true
echo -e "${GREEN}Language, locales and keyboard configured.${NC}"
}
_prefs_audio() { _prefs_audio_menu; }
_system_preferences_menu() {
while true; do
local choice
choice=$(_menu "System Preferences" "Select a preference group:" \
$TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
"1" "Date, Time & Timezone" \
"2" "Language, Locales & Keyboard" \
"3" "Audio & Sound Stack" \
"4" "Back to main menu")
[ -z "$choice" ] && return
clear
case "$choice" in
1) _prefs_date_time ;;
2) _prefs_locale_keyboard ;;
3) _prefs_audio ;;
4) return ;;
esac
done
}
+2 -2
View File
@@ -109,7 +109,7 @@ _ensure_time_synced() {
if [ -n "${DISPLAY:-}" ] || [ -n "${SSH_TTY:-}" ]; then
_msg "Timezone" \
"Your system timezone is not set or is set to UTC.\n\nThe script will now open the timezone\nconfiguration tool to set your local timezone." 12 60
sudo dpkg-reconfigure tzdata
sudo env LC_ALL=C LANGUAGE=C dpkg-reconfigure tzdata || true
echo -e "${GREEN}Timezone configured: $(timedatectl show -p Timezone --value 2>/dev/null)${NC}"
else
echo -e "${YELLOW}Timezone not set. Run 'sudo dpkg-reconfigure tzdata' later.${NC}"
@@ -163,7 +163,7 @@ detect_debian_version() {
# CPU and RAM info (cosmetic)
# ----------------------------------
detect_cpu_ram() {
CPU_SUMMARY=$(grep -m1 'model name' /proc/cpuinfo | sed 's/.*: //')
CPU_SUMMARY=$(grep -m1 'model name' /proc/cpuinfo | sed 's/.*: //' || true)
RAM_KB=$(grep MemTotal /proc/meminfo | awk '{print $2}')
RAM_GB=$(awk -v kb="$RAM_KB" 'BEGIN { printf "%.2f", kb / 1048576 }')
RAM_SUMMARY="${RAM_GB} GB"