Compare commits

..

10 Commits

Author SHA1 Message Date
stornic56 ba72fd9f87 add GRUB timeout TUI and restructure boot menu
- Rename "Boot Rescue & Repair" to "Boot Rescue + GRUB"
- Add interactive GRUB timeout settings (Disable, 3s, 5s, Custom)
- Implement robust `_set_grub_var` and `_apply_grub_setting` helpers
- Add /etc/default/grub.d/99_script_override.cfg to bypass VM/Cloud-init overrides
- Handle Secure Boot countdown policy restrictions by using menu style
- Fix independent install check for lightdm and lightdm-gtk-greeter-settings
2026-07-12 00:13:08 -05:00
stornic56 f043c130a8 clean TUI core
- Stripped forced-scrollbar hack from _menu and _checklist
- Eliminated TUI_ANCHO_REFORZADO overflow across 9 files
- Removed redundant _inst() function globally
- Added dynamic list height calculation for checklists
- Introduced Desktop & Display menu (Option 12)
- Fixed non-free-firmware false positive in repo detection
- Restored terminal transparency for apt/vainfo output"
2026-07-11 22:05:35 -05:00
stornic56 2ebb33460c Broadcom, Utils & Headless Fixes
- Removed dead Broadcom hardware IDs (4357/4358/4360/4727) from `_is_broadcom_b43`, retaining only valid ID 4352 to eliminate false positives in the case statement.
- Added a guard in `_handle_wireless` Level 3 to verify `linux-headers` availability via `apt-cache policy`. Skips DKMS compilation if headers are missing, preventing transaction failures during installation.
- Implemented Broadcom combo card detection (WiFi + Bluetooth) by scanning `PCI_BT_DEVS`. Automatically writes `/etc/modprobe.d/broadcom-combo.conf` with `softdep wl post: btusb` and warns users about potential reboot requirements.
- Enhanced Level 2 (`firmware-b43-installer`) with post-installation validation for `/lib/firmware/b43`. Provides clear recovery instructions via `sudo dpkg-reconfigure firmware-b43-installer` if the directory is empty or missing after installation.
- Created a new helper `_msg_red()` in `utils.sh` to handle critical error messages with colored Whiptail output, replacing standard alerts for migration warnings and failures.
- Updated `repos/migrate.sh` to use `_msg_red()` for branch migration warnings and failure states, ensuring visibility of critical issues while keeping completion messages informative.
- Verified headless mode guards across 16 separate extras files (`office.sh`, `fetch.sh`, `cursors.sh`, etc.), preventing unnecessary package installations on servers without display environments.
- Completed syntax verification (`bash -n`) across all core and extra modules, ensuring no errors in the updated logic for firmware, gaming, swap, or repository management scripts.
- update readme.md
2026-07-10 19:50:36 -05:00
stornic56 a91b0caa25 critical-fixes, swap module & gaming overhaul
- Fixed script crashes from `whiptail` Cancel/Esc under `set -e`. Added `_menu()`, `_checklist()` and `_inputbox()` wrappers with `|| true` to prevent premature exits.
- Resolved startup failures by using defaults instead of relying on unset variables with `set -u`.
- Hardened sudoers management — `_validate_sudoers()` writes to temp file, validates with `visudo -cf`, only copies if successful.
- Replaced `eval` in `_run_cmd` with safer `bash -c` execution.

Swap Management Module (`modules/swap.sh`)
- New standalone module with 9 internal functions and `manage_swap()` entry point.
- Btrfs CoW detection — applies `chattr +C` before swapfile creation to prevent mkswap rejection on Btrfs.
- Dynamic swappiness configuration — reads current system value instead of hardcoding 60, pre-fills inputbox with existing setting.
- Uses `/run/lock/debianito-swap.lock` for early init compatibility (added as option 9 in main menu).

Repository & Branch Migration (`modules/repos/migrate.sh`)
- Handles branch migration from stable (11/12) to Testing or SID with 5-screen UX flow.
- Persistent backup system — creates timestamped tar.gz backups of `/etc/apt/sources.list*`, auto-restores on apt update failure.
- SID guardrails — installs `apt-listbugs` and `apt-listchanges` before upgrade to warn about critical bugs in unstable packages.
- Dynamic menu options based on Debian version (SID shows only 1-2-3 Exit, non-SID includes backports + branch migration).
- New `_components_enabled()` helper detects current contrib/non-free state.

Gaming Module Overhaul
- Unified gaming checklist — merged i386 toggle into single prompt with lazy evaluation instead of separate pre-check.
- Lazy 32-bit architecture enablement — only enables i386 when needed (steam/lutris/i386 selected) and installs graphics drivers if `need_32bit=true`.
- New `_install_nvidia_32bit()` helper with proper driver detection, version pinning, and legacy/tesla variant handling.

Heroic & OpenRGB Downloads
- Heroic — fetches latest release from GitHub API using `jq` to extract amd64.deb URL, validates with `dpkg-deb --info`.
- OpenRGB — downloads from Codeberg Gitea API with SHA256 verification when available, fallback to `dpkg-deb` validation.
- Dynamic codename detection — now detects Bookworm vs Trixie at runtime instead of hardcoded static values for .deb download URLs.

|Other Improvements
- Renumbered main menu: 8=ZRAM, 9=Swap Management, 10=Extras, 11=Boot Rescue, 12=Exit.
- Improved `detect_storage()` — excludes loop/CD-ROM devices via `lsblk -e 7,11`, explicitly skips zram, detects USB/SD via `/sys/block/$name/removable`.
- Standardized SCROLL_HINT across all files with centralized readonly variable.
2026-07-10 01:42:57 -05:00
stornic56 4ef48eac3b NTP Sync, LightDM, Wine & Rescue Updates
-  System Time (NTP)*: Overhauled `modules/utils.sh`. `check_system_time()` now warns if year < 2025 and enables NTP silently if off but valid. `sync_system_time()` conditionally installs/starts `systemd-timesyncd` and verifies synchronization via `timedatectl NTPSynchronized`.
- LightDM Configuration: Added `_configure_lightdm()` to ensure the user list is visible in the greeter. Installs `lightdm-gtk-greeter-settings` and creates an override config (`99-show-users.conf`) during startup without interrupting the flow.
- Wine Installation: Simplified Wine setup in `system.sh` and Bullseye `extras.sh`. Removed i386 multiarch logic; now installs only `wine64 fonts-wine`. Added post-install version verification to confirm successful deployment.
- Lutris Dependencies: Updated `install_lutris()` in `tools.sh` and `legacy.sh`. Now conditionally adds `wine32` only if the system supports i386 architectures, preventing dependency failures on 64-bit-only setups.
- Boot Rescue Module: Created new standalone `modules/rescue.sh`. Provides UEFI boot repair tools: Secure Boot refirm (shim + GRUB) and Initramfs regeneration for all kernels. Integrated into the main menu as a dedicated rescue section.
- update docs
2026-07-01 00:31:54 -05:00
stornic56 110d89baf8 WiFi Detection, vainfo & Java JRE
- Implemented multi-layered WiFi detection logic in `utils.sh`. Added PCI class text grep, exact `lspci -d ::0280` matching for wireless devices, Broadcom vendor ID fallback (`14e4`), and USB discovery via `lsusb`. Improved `sysinfo.sh` fallback message to guide users toward the Firmware option.
- Added `_pause()` execution after `vainfo` outputs in `gpu/_helpers.sh` (`offer_generic_tools`) and `gpu/amd_intel.sh` (`offer_amd_tools`, `offer_intel_tools`). Ensures users can review hardware info before proceeding with tool installation.
- Refactored Java selection in `extras/java.sh`. Switched from single-option `--menu` to multi-select `--checklist`, enabling simultaneous Temurin JRE installations with all versions enabled by default and iterative installation logic.
2026-06-28 11:48:48 -05:00
stornic56 8d1a05e3e0 UX Refactor: Pauses, Status & WiFi
- Implemented global `_pause()` logic across all modules (`utils`, `gaming`, `firmware`, etc.), replacing hardcoded `read -p` calls to standardize exit pauses.
- Unified MangoHud installation into a single command (`apt install -y mangohud:i386`) for gaming and legacy branches.
- Refactored `_inst()` to return `*` instead of `(installed)`, moving the function globally to `utils.sh` and removing duplicates from helpers.
- Enhanced Broadcom WiFi detection with expanded grep patterns ('network controller', 'wireless', etc.) and ID fallback (`14e4`).
- Updated `_run_cmd` to integrate the new pause logic for consistent workflow interruptions during script execution.
2026-06-27 00:21:09 -05:00
stornic56 ad0b39e159 lang & firefox-esr
- Added `_detect_lang()` helper to `modules/utils.sh` (extracts first 2 chars from `$LANG`, fallback to `en`).
- Created `_detect_lang_pkg()` utility for LibreOffice localization: handles regional variants (`es-ar` → `es`) and skips English packages.
- Implemented `_check_network()` with cascade methods (ping→wget→curl) in `modules/utils.sh`. Warning-only pre-flight check after `check_sudo` in `debianito.sh`, compatible with `set -euo pipefail`.
- Fixed system time validation: changed `2026` threshold to `2025` in `check_system_time()` (replaced self-referential `$(date +%Y)` which always evaluated false).
- Refactored LibreOffice language selection in `office.sh`: replaced 10 lines of inline logic with `_detect_lang_pkg "libreoffice-l10n"`.
- Overhauled Firefox ESR integration in `internet.sh`: added state detection, mutual exclusion guard (both Firefox variants selected → warning), new `install_firefox_esr()` function with language support.
- Updated `install_firefox_mozilla()`: added Debian version guard (`<12`), replaced `_run_install` with `_run_cmd`.
- Standardized header in internet menu and improved whiptail UX for Firefox options.
2026-06-25 22:06:15 -05:00
stornic56 3972cc4811 Bluetooth Fix & GPU ID Expansion
- Bluetooth Package Cleanup: Replaced deprecated `bluez-utils` with `bluez-tools` in `modules/bluetooth.sh` and `modules/firmware.sh`. Ensures compatibility across all Debian versions.
- Maxwell GPU Detection: Added 4 ID blocks (`0x1340 – 0x17FF`, 480 IDs total). Captures missing cards: 980M/970M, Quadro M laptop, GTX 960/950, Quadro M2000, TITAN X, GTX 980 Ti, Quadro M6000, and Tesla M40.
- Pascal GPU Detection: Expanded 5 ID blocks (`0x15F0 – 0x1D7F`, 528 IDs total). Added support for TITAN Xp, GTX 1080 Ti, and Quadro P-series. Unified GP106/107 ranges and bounded end at `0x1D7F` to prevent Turing conflicts.
- Validation: Passed `bash -n` checks on all modified files. Confirmed zero ID collisions between Maxwell, Fermi, Kepler, and Pascal architectures.
2026-06-23 23:18:37 -05:00
stornic56 2272306313 NVIDIA Fermi/Kepler Fixes & Utils
- Refined NVIDIA GPU detection in `_helpers.sh`. Corrected Kepler GK208 range (`0x1280–0x12BF`) and added refined Fermi ID ranges to eliminate device collisions across architectures.
- Updated `gpu.sh` driver logic for Debian Bookworm (explicit Fermi veto) and Trixie (unified Kepler/Fermi check). Prevents legacy driver conflicts and ensures correct selection per version.
- Cleaned `bullseye/legacy.sh`. Removed outdated Fermi checks with collisions; now inherits unified validation from `_helpers.sh` to maintain Debian 11 compatibility.
- Fixed Wi-Fi interface regex in `utils.sh`. Added `wlan*` pattern to catch ath9k interfaces (`wlan0`) alongside standard wl/wlp/wlo identifiers.
- Validated syntax across all files with `bash -n`. Confirmed zero collision between Fermi and Kepler device IDs, ensuring stable detection on Debian 11/12/
2026-06-22 18:39:16 -05:00
46 changed files with 2373 additions and 1091 deletions
+50 -13
View File
@@ -50,15 +50,17 @@ After running the script:
| **1** | [System Info](/docs/system_info.md) | Show detected OS, CPU, RAM, GPU and hardware details |
| **2** | [User Privileges & Feedback](/docs/user_priv_feed.md) | Configure sudo group membership, enable passwordless sudo for frequent tasks, repair home directory ownership issues, and toggle visual password feedback (asterisks) in terminal |
| **3** | [Configure Repositories](/docs/repos_config.md) | Setup official repos with non-free/contrib options, optional Backports support and Deb822/classic format injection.|
| **4** | [Firmware & Wireless Drivers](/docs/firmware.md) | Install essential firmware for GPUs and wireless|
| **4** | [Firmware, Wireless & Bluetooth](/docs/firmware.md) | Install essential firmware for GPUs and wireless|
| **5** | [Graphics Drivers & Mesa Stack](/docs/gpu.md) | Configure AMD/Intel/NVIDIA drivers and Mesa graphics stack + monitoring tools |
| **6** | [Backports Kernel](/docs/kernel.md) | Install latest kernel from Debian backports|
| **7** | [Gaming Setup and Performance](/docs/gaming.md)| Steam, Heroic Games Launcher, [RetroArch](/docs/retroarch.md) GameMode, MangoHud, OpenRGB, Java JRE (Temurin 8/17/21) |
| **8** | [Install ZRAM](/docs/zram.md)| Configure compressed RAM for memory optimization|
| **9** | Install Programs and Software | Selection from several categories (Development, Themes, System, etc.) |
| **10** | Exit | Return to terminal |
| **7** | [Gaming Setup ](/docs/gaming.md)| Steam, Heroic Games Launcher, [RetroArch](/docs/retroarch.md) GameMode, MangoHud, OpenRGB, Java JRE (Temurin 8/17/21) |
| **8** | [ZRAM](/docs/zram.md)| Configure compressed RAM for memory optimization|
| **9** | Swap Management| Manage swap file or partition size and enable/disable swap space for system stability|
| **10** | Install Programs and Software | Browse and install packages by category (Development, Themes, System Tools, etc.) using APT |
| **11** | Boot Rescue & Repair| Fix GRUB bootloader issues, chroot repair, or restore system boot configuration|
| **12** | Exit | Return to terminal |
### Install Programs and Software (Option 9)
### Install Programs and Software (Option 10)
The submenu offers the next categories:
@@ -67,12 +69,12 @@ The submenu offers the next categories:
| **0** | Essential Pack | Quick install of common tools (compression, system info, VLC, MS fonts)|
| **1** | Customization System | Desktop themes, icon themes, cursor themes, and fonts |
| **2** | Download & Network | Downloaders (aria2, ytdlp, FileZilla) + Torrent clients (qBittorrent, Deluge, Transmission) |
| **3** | Internet (Browsers, Email Clients, VPN Tools) | Web browsers (Firefox/Mozilla, LibreWolf, Floorp, Chromium, Brave, Tor), email clients (Thunderbird), and VPN tools including Riseup |
| **3** | Internet (Browsers, Email Clients, VPN) | Web browsers (Firefox/Mozilla, LibreWolf, Floorp, Chromium, Brave, Tor), email client (Thunderbird), and VPN tools (RiseUp, Proton, Mullvad)|
| **4** | Media Players | Multimedia playback with VLC media player and MPV for advanced video/audio support |
| **5** | Multimedia & Design | image editing (GIMP), video editing (Kdenlive, HandBrake), 3D modeling (Blender), audio recording (Audacity), and graphics design (Inkscape) |
| **6** | Code Editors & IDEs | vim, vim-gtk3, Neovim, Helix, nano, Emacs, Kate, Mousepad, Gedit, Geany, GNOME Text Editor, and VSCodium (VS Code open-source) |
| **7** | Servers & Dev Tools | Web servers (Nginx/Apache), databases (PostgreSQL/MariaDB), Java Development Kit (Temurin 17/21/25 JDK), Docker, Python, SSH tools, fail2ban, Jellyfin Server and essential utilities |
| **8** | Security & Networking | Wireshark, tcpdump, Zenmap, ClamAV, UFW, Fail2ban |
| **7** | Servers & Dev Tools | Web servers (Nginx/Apache), databases (PostgreSQL/MariaDB), Java Development Kit (Temurin 17/21/25 JDK), Docker, Python, SSH tools, Jellyfin Server and essential utilities |
| **8** | Security & Networking | Wireshark, tcpdump, Zenmap, ClamAV, UFW, fail2ban |
| **9** | Software Centers | Choose a software store to install. |
| **10** | System Tools | htop/btop, ncdu, Timeshift, tmux/screen, nvme-cli, Flatpak support, extension repository manager and qemu/virtmanager |
| **11** | Fetch / System Info | fastfetch/neofetch, hyfetch, Linux logo and screenfetch |
@@ -84,9 +86,42 @@ The submenu offers the next categories:
| Directory/File | Description |
|----------------|-------------|
| `./debianito.sh` | Main entry point; handles menu navigation and system detection. |
| `/modules/` | Modular scripts for specific tasks: sudo config, repos, firmware, gpu, kernel, gaming, zram. |
| `/modules/extras/` | Split-by-category sub-modules for the "Install Programs and Software" menu (Option 9). |
| `debianito.sh` | Main entry point; handles menu navigation and system detection. |
| `docs/` | Documentation directory containing Markdown files for each module. |
| `modules/` | Core modular scripts organized by category: repos, gpu, gaming, kernel, firmware, zram, etc. |
| `modules/bullseye/` | Legacy Debian 11 (Bullseye) specific modules: `extras.sh`, `legacy.sh`, `repos.sh`. |
| `modules/extras/` | Software installer sub-modules split by category (themes, downloaders, internet, dev tools, etc.). |
| `modules/gaming/` | Gaming launcher and optimization scripts: Steam, Heroic, Lutris, performance tools. |
| `modules/gpu/` | GPU driver installation scripts for AMD and NVIDIA with architecture detection. |
| `modules/repos/` | Repository management scripts: migration tool (`migrate.sh`) and format detection (`repo_detect.sh`). |
| `modules/extras/design/` | Multimedia & design tools installer (Blender, GIMP, Kdenlive, OBS). |
| `modules/extras/dev/` | Development tools installer with special handling for Jellyfin and Java. |
| `modules/extras/download/` | Download tools installer (aria2, FileZilla) and torrent clients (qBittorrent, Transmission). |
| `modules/extras/essential/` | Essential package installer for basic system utilities on older Debian versions. |
| `modules/extras/fetch/` | System information fetcher tools (neofetch, screenfetch, linuxlogo). |
| `modules/extras/internet/` | Internet tools installer: browsers, email clients, download managers. |
| `modules/extras/java.sh` | Java runtime installer for Minecraft and development (Temurin 8/17/21). |
| `modules/extras/office/` | Office productivity suite installer (LibreOffice, GIMP alternatives). |
| `modules/extras/players/` | Media player installer (MPV, VLC) with codec support. |
| `modules/extras/programming/` | Code editors and IDEs installer (Vim, Neovim, Emacs, Kate). |
| `modules/extras/security/` | Security tools installer: ClamAV, Fail2Ban, UFW, Wireshark. |
| `modules/extras/system/` | System utilities installer with software center options (GNOME Software, Discover). |
| `modules/extras/themes/` | Desktop customization installer: themes, icons, cursors, fonts. |
| `modules/gaming/_helpers.sh` | Shared helper functions for gaming modules (32-bit support, Mesa drivers). |
| `modules/gpu/amd_intel.sh` | AMD and Intel GPU firmware + monitoring tools (radeontop, nvtop, vainfo). |
| `modules/gpu/_helpers.sh` | Shared helper functions for GPU detection (NVIDIA architecture checks). |
| `modules/nvidia.sh` | NVIDIA driver installer with multi-architecture support (Kepler, Fermi, Maxwell, Pascal, Blackwell). |
| `modules/amd_intel.sh` | AMD and Intel GPU firmware + monitoring tools installation. |
| `modules/kernel.sh` | Kernel management: backports kernel installation and detection. |
| `modules/repos/migrate.sh` | Branch migration tool for Debian stable → testing/SID with backup/rollback. |
| `modules/repos/repo_detect.sh` | Repository format detection (DEB822 vs classic) for idempotent configuration. |
| `modules/rescue.sh` | Boot rescue and repair tools: GRUB fix, chroot repair, system restore. |
| `modules/sudo_config.sh` | Sudo configuration: group membership, passwordless sudo, home directory ownership. |
| `modules/swap.sh` | Swap management: file/partition size configuration and enable/disable swap space. |
| `modules/sysinfo.sh` | System information detection and display (OS, CPU, RAM, GPU, storage). |
| `modules/utils.sh` | Utility functions shared across modules (color codes, confirmation dialogs, installation helpers). |
| `modules/zram.sh` | ZRAM configuration for compressed RAM optimization. |
| `README.md` | Project documentation and usage instructions. |
```bash
├── debianito.sh
@@ -158,15 +193,17 @@ The submenu offers the next categories:
│   ├── gpu.sh
│   ├── kernel.sh
│   ├── repos
│   │   ├── migrate.sh
│   │   └── repo_detect.sh
│   ├── repos.sh
│   ├── rescue.sh
│   ├── sudo_config.sh
│   ├── swap.sh
│   ├── sysinfo.sh
│   ├── utils.sh
│   └── zram.sh
└── README.md
```
---
> 🤖 **AI-Assisted Development Note**
+34 -10
View File
@@ -28,6 +28,9 @@ source "${MODULES_DIR}/repos.sh"
[ -f "${MODULES_DIR}/extras.sh" ] && source "${MODULES_DIR}/extras.sh"
[ -f "${MODULES_DIR}/zram.sh" ] && source "${MODULES_DIR}/zram.sh"
[ -f "${MODULES_DIR}/extras/java.sh" ] && source "${MODULES_DIR}/extras/java.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"
# ── Bullseye-specific modules (loaded only on Debian 11) ──
if [ -d "${MODULES_DIR}/bullseye" ]; then
@@ -42,15 +45,17 @@ DEBIAN_CODENAME=""
main_menu() {
# Auto-adjust TUI dimensions for small terminals
if [ "$LINES" -lt $((TUI_ALTO + 6)) ] || [ "$COLUMNS" -lt $((TUI_ANCHO + 6)) ]; then
if [ "${LINES:-24}" -lt $((TUI_ALTO + 6)) ] || [ "${COLUMNS:-80}" -lt $((TUI_ANCHO + 6)) ]; then
TUI_ALTO=$((LINES - 4 > 8 ? LINES - 4 : 8))
TUI_ANCHO=$((COLUMNS - 4 > 50 ? COLUMNS - 4 : 50))
TUI_ALTO_LISTA=$((TUI_ALTO - 10 > 4 ? TUI_ALTO - 10 : 4))
fi
while true; do
sudo -v >/dev/null 2>&1 || true
local STATE_REFRESHED=false
local choice
choice=$(whiptail --title "DEBIANITO — simple configurator script" --menu "" \
choice=$(_menu "DEBIANITO — simple configurator script" "" \
$TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
"1" "System Info" \
"2" "User Privileges & Feedback" \
@@ -59,10 +64,12 @@ main_menu() {
"5" "Graphics Drivers & Mesa Stack" \
"6" "Backports Kernel" \
"7" "Gaming Setup" \
"8" "ZRAM (Swap)" \
"9" "Install Programs and Software" \
"10" "Exit" \
3>&1 1>&2 2>&3)
"8" "ZRAM" \
"9" "Swap Management" \
"10" "Install Programs and Software" \
"11" "Boot Rescue + GRUB" \
"12" "Desktop & Display" \
"13" "Exit")
clear
@@ -75,6 +82,7 @@ main_menu() {
else
configure_repos || true
fi
STATE_REFRESHED=true
;;
4)
if [ "$DEBIAN_VERSION" = "11" ] && type install_firmware_bullseye &>/dev/null; then
@@ -83,7 +91,7 @@ main_menu() {
install_firmware || true
fi
;;
5) install_gpu_drivers || true ;;
5) install_gpu_drivers || true; STATE_REFRESHED=true ;;
6)
if [ "$DEBIAN_VERSION" = "11" ]; then
_msg "Not Available" \
@@ -93,6 +101,7 @@ kernels. Use the stable kernel provided by Bullseye." 10 60
else
install_kernel_backports || true
fi
STATE_REFRESHED=true
;;
7)
if [ "$DEBIAN_VERSION" = "11" ] && type install_gaming_bullseye &>/dev/null; then
@@ -100,24 +109,38 @@ kernels. Use the stable kernel provided by Bullseye." 10 60
else
install_gaming || true
fi
STATE_REFRESHED=true
;;
8) install_zram || true ;;
9)
9) manage_swap || true; STATE_REFRESHED=true ;;
10)
if [ "$DEBIAN_VERSION" = "11" ] && type install_extras_bullseye &>/dev/null; then
install_extras_bullseye || true
else
install_extras || true
fi
;;
10) echo "Exiting."; exit 0 ;;
11) rescue_boot || true ;;
12) manage_desktop_display || true ;;
13) echo "Exiting."; exit 0 ;;
esac
if $STATE_REFRESHED; then
refresh_system_state
fi
done
}
check_root
check_sudo
if ! _check_network; then
echo -e "${YELLOW}──────────────────────────────────────────${NC}"
echo -e "${YELLOW} No internet connectivity detected.${NC}"
echo -e "${YELLOW} Package installation will fail without network.${NC}"
echo -e "${YELLOW} You can use: System Info, User Privileges, and${NC}"
echo -e "${YELLOW} other offline features.${NC}"
echo -e "${YELLOW}──────────────────────────────────────────${NC}"
fi
check_system_time
sync_system_time
detect_debian_version
detect_cpu_ram
@@ -127,6 +150,7 @@ detect_network
detect_displayserver
detect_storage
detect_desktop_environment
_configure_lightdm
detect_audio_server
# ── Bullseye-specific init (archive phase) ──
+26 -7
View File
@@ -116,16 +116,35 @@ This approach eliminates the security risk of running OpenRGB as root while main
| **Temurin 17** | Modern Minecraft servers, newer game clients | Balances performance and compatibility for post-1.16+ game versions |
| **Temurin 21** | Latest game engines, cutting-edge mods | Provides best performance for modern Java applications |
The script injects the official Adoptium repository to pull community-maintained builds rather than Oracle's proprietary JRE:
```bash
# Repository injection logic (simplified)
echo "deb [signed-by=/etc/apt/keyrings/adoptium.asc] https://packages.adoptium.net/artifactory/deb $(awk -F= '/^VERSION_CODENAME/{print$2}' /etc/os-release) main" | sudo tee /etc/apt/sources.list.d/adoptium.list
```
**Repository Management via extrepo:** The script leverages the `extrepo` utility to manage external repositories cleanly rather than manually injecting repository URLs into system files. This approach offers several advantages:
**Version Selection Logic:** Users can choose which Temurin version to install based on their specific game requirements. The module justifies offering all three versions because:
1. **Automated Keyring Handling:** `extrepo` manages GPG keys and source file configurations automatically, eliminating manual intervention with `/etc/apt/sources.list.d/`.
2. **Dependency Resolution:** The utility checks for its own installation and handles the enabling of the Adoptium Temurin repository before proceeding with package installation.
3. **Maintenance Safety:** Updates to the upstream repository are reflected through `extrepo` without requiring direct edits to system configuration files, reducing the risk of breakage during OS updates.
**Version Selection Logic:** Users can choose which Temurin version to install based on their specific game requirements via a TUI menu (`install_minecraft_java()`). The module justifies offering all three versions because:
1. **Backward Compatibility:** Java 8 remains in use by many Minecraft mods and older game clients that haven't been updated for newer JVMs
2. **Performance Optimization:** Java 21 provides the best performance characteristics for modern games with heavy multithreading requirements
3. **Security Updates:** All Temurin versions receive regular security patches from the Eclipse Foundation community
The installation process ensures clean repository management without polluting the system with multiple conflicting JRE installations, maintaining Debian's package integrity while providing flexibility for different gaming scenarios.
The installation process ensures clean repository management without polluting the system with multiple conflicting JRE installations, maintaining Debian's package integrity while providing flexibility for different gaming scenarios. It automatically installs `extrepo` if not present and enables the Adoptium source before proceeding with version-specific packages (e.g., `temurin-8-jre`, `temurin-17-jre`).
### References:
- [https://wiki.debian.org/Steam](https://wiki.debian.org/Steam)
- [wiki.archlinux.org/title/Steam](wiki.archlinux.org/title/Steam)
- [https://repo.steampowered.com/steam/](https://repo.steampowered.com/steam/)
- [https://www.protondb.com/](https://www.protondb.com/)
- [https://github.com/lutris/lutris](https://github.com/lutris/lutris)
- [https://github.com/lutris/docs/blob/master/InstallingDrivers.md](https://github.com/lutris/docs/blob/master/InstallingDrivers.md)
- [https://github.com/Heroic-Games-Launcher/HeroicGamesLauncher](https://github.com/Heroic-Games-Launcher/HeroicGamesLauncher)
- [https://github.com/flightlessmango/Mangohud](https://github.com/flightlessmango/Mangohud)
- [https://github.com/feralinteractive/gamemode](https://github.com/feralinteractive/gamemode)
- [https://gitlab.com/CalcProgrammer1/OpenRGB](https://gitlab.com/CalcProgrammer1/OpenRGB)
- [https://adoptium.net/es/installation/linux](https://adoptium.net/es/installation/linux)
+8 -6
View File
@@ -48,7 +48,8 @@ This "detect-then-deploy" model prevents users from installing unnecessary drive
| **Gen4** (Broadwater) | 65nm | GMA X4500, GMA X4500HD | `i915` | `i915` | Not supported | Predecessor to HD Graphics. Very limited support. The i915 DRI driver is the original, now obsolete. |
| **Gen5** (Ironlake) | 32nm | HD Graphics (Westmere/Arrandale) | `i915` | `crocus` | Not supported | First generation "HD Graphics". OpenGL up to 3.3 only. Legacy driver `i965` was **removed** in Mesa 24.1, so `crocus` is now the only option. |
| **Gen6** (Sandy Bridge) | 32nm | HD Graphics 2000/3000 | `i915` | `crocus` | Not supported | Significant performance improvement. Maximum OpenGL 3.3. |
| **Gen7** (Ivy Bridge) | 22nm | HD Graphics 2500/4000 | `i915` | `crocus` | Not supported | First generation at 22nm. `crocus` is the recommended driver. |
| **Gen7** (Ivy Bridge) | 22nm | HD Graphics 2500/4000 | `i915` | `crocus` | `ANV/HASVK` [(incomplete/broken)](https://www.reddit.com/r/vulkan/s/Hnf5zU8WZY) | First Gen at 22nm. `crocus` is the recommended OpenGL driver. Vulkan is exposed but completely non-conformant (0.0.0.0 ), lacks basic features (e.g., texture swizzle), and is [unusable for real-world tasks](https://www.phoronix.com/news/Intel-HasVK-Drop-Dead-Code).|
| **Gen7** (Bay Trail) | 22nm | HD Graphics (Bay Trail) | `i915` | `crocus` | `ANV`[(incomplete)](https://lists.debian.org/debian-user/2023/07/msg00550.html) | `conformanceVersion = 0.0.0.0` Support is experimental up to Vulkan 1.2, lacks basic extensions, and may cause instability. The separate HASVK driver exists but is not used on this system. |
| **Gen7.5** (Haswell) | 22nm | HD Graphics 4600, Iris Pro 5200 | `i915` | `crocus` | `hasvk` | Vulkan support via community driver `hasvk` (Vulkan 1.3). |
| **Gen8** (Broadwell) | 14nm | HD Graphics 5300, Iris Pro 6200, Iris 6100 | `i915` | `iris/crocus` | `hasvk` | First generation at 14nm, `iris` becomes the main OpenGL driver. |
| **Gen9** (Skylake) | 14nm | HD Graphics 530, Iris 540/550 | `i915` | `iris` | `anv` | Mature architecture with strong Linux support. Major performance boost for iGPU. |
@@ -59,7 +60,7 @@ This "detect-then-deploy" model prevents users from installing unnecessary drive
| **Xe2-LPG** (Lunar Lake) | TSMC N3B | Arc Graphics (Xe2-LPG - 8 Xe-Cores) | `i915?/xe` | `iris` | `anv` | First iGPU with Xe2 architecture (Battlemage). |
| **Xe3-LPG** (Panther Lake) | Intel 18A | Arc Graphics (Xe3 iGPU) | `i915?/xe` | `iris` | `anv` | High-power iGPU. Requires Kernel 6.19 and Mesa 26 as base. |
| **Xe-HPG** (Alchemist) | TSMC N6 | **Arc A380, A580, A750, A770** (dGPU) | `i915/xe` | `iris` | `anv` | First modern dGPU (Arc). Support since Kernel 6 and Mesa 22. |
| **Xe2-HPG** (Battlemage) | TSMC N5 | **Arc B580, B570** (dGPU) | `i915/xe` | `iris` | `anv` | Second generation dGPU. Very solid day-one Linux support since Kernel 6.12 and Mesa 24.2 |
| **Xe2-HPG** (Battlemage) | TSMC N5 | **Arc B570, B580** (dGPU) | [`i915/xe`](https://www.phoronix.com/review/intel-xe-i915-linux-619) | `iris` | `anv` | Second generation dGPU. Very solid day-one Linux support since Kernel 6.12 and Mesa 24.2 |
---
@@ -71,6 +72,7 @@ This "detect-then-deploy" model prevents users from installing unnecessary drive
* **Legacy Hardware (Gen5-Gen8)**: The classic `i965` driver was **officially removed from Mesa in version 24.1**. **[`crocus`](https://www.phoronix.com/news/Intel-Crocus-Default-Gallium3D)** (Gallium3D) is the only active driver for this legacy hardware.
* **Modern Hardware (Gen9 and Xe)**: **`iris`** is the standard driver. It works excellently on both iGPUs and Arc dGPUs (Alchemist/Battlemage).
* **Vulkan**:
* **Old Hardware about Ivy Bridge and Bay Trail (Gen7)**: Although the ANV/HASVK drivers expose these GPUs as Vulkan devices (reporting API versions as high as 1.2 or 1.3), their state is completely non-compliant (conformanceVersion = 0.0.0.0). The support is purely theoretical, it lacks basic hardware features (e.g., texture swizzle on Ivy Bridge) and is unstable or unusable for real-world applications. Because of this, in Mesa 22.3, the Gen7/Gen8 Vulkan code was separated from the main driver (ANV) and moved to the legacy HASVK driver to avoid hindering the development of modern hardware. You can read the technical details of this decision [here](https://www.phoronix.com/news/Intel-HASVK-Old-Vulkan-Gen7-8).
* **Legacy Hardware (Gen7.5 - Gen8)**: Uses **[`hasvk`](https://www.phoronix.com/news/Intel-ANV-HASVK-Split-Merged)**, a community-maintained driver (not directly by Intel engineers), offering Vulkan 1.2? on 2013-era hardware.
*Additionally, in early 2024, the compiler code shared between `iris` and `anv` for [Gen8](https://www.phoronix.com/news/Intel-Mesa-Splitting-Gen8) was also isolated, following the same principle: to enable faster development for modern hardware without breaking Broadwell support*.
* **Modern Hardware (Gen9+)**: **[`anv`](https://docs.mesa3d.org/drivers/anv.html)** is Intel's official driver. On recent hardware (Gen12+, Arc) it reaches the **Vulkan 1.4 standard**.
@@ -118,7 +120,7 @@ These generations depend **exclusively** on the proprietary driver and closed st
| :--- | :--- | :--- | :--- | :--- | :--- | :--- |
| **Fermi**<br>*(GF100/110)* | **390.xx** (Legacy) | `nvidia` (Closed) | **Vulkan 1.0** | No | **CUDA 8.0** | Last driver to support this architecture. Has not received security fixes for years. Only viable for completely offline systems. |
| **Kepler**<br>*(GK100/110)* | **470.xx** (Legacy) | `nvidia` (Closed) | **Vulkan 1.2** | No | **CUDA 11.8** | Last generation to receive "Legacy" status. Good compatibility with OpenGL 4.6, but Vulkan support stalled at 1.2. |
| **Maxwell**<br>*(GM100/200)* | **580.xx** (Old Standard) | `nvidia` (Closed) | **Vulkan 1.3** | No | **CUDA 12.0** | Removed from official support in driver 555 (CUDA 12.1). Requires pinning system to branch 550. |
| **Maxwell**<br>*(GM100/200)* | **580.xx** (Old Standard) | `nvidia` (Closed) | **Vulkan 1.3** | No | **CUDA 12.0** | Removed from official support in driver 580 (CUDA 12.1). |
| **Pascal**<br>*(GP100/102/104)* | **580.xx** (Old Standard) | `nvidia` (Closed) | **Vulkan 1.3** | No | **CUDA 12.0** | Shares same fate as Maxwell. Still very popular (GTX 1060/1080), but requires blocking packages (e.g., in Debian) to prevent updates that break graphics support. |
---
@@ -131,7 +133,7 @@ Starting with Turing, NVIDIA introduced the **open kernel module**. From driver
| **Turing**<br>*(TU100/102/116)* | 525.xx to 610+ | `nvidia` (**Open Module**) | **Vulkan 1.3** | **Yes** (Vulkan 1.3) | **CUDA 12.8+** | First generation to use Open Kernel Module (introduced in 515, default in 525). *Note:* Security processor firmware (GSP) remains a closed blob. Excellent NVK support. |
| **Ampere**<br>*(GA100/102/104/107)* | 525.xx to 610+ | `nvidia` (**Open Module**) | **Vulkan 1.3** | **Yes** (Vulkan 1.3) | **CUDA 12.8+** | Mature support in both proprietary driver and NVK. For RTX 3060/3080/3090, NVK offers extremely competitive performance versus proprietary in many scenarios. |
| **Ada Lovelace**<br>*(AD100/102/103/104)* | 525.xx to 610+ | `nvidia` (**Open Module**) | **Vulkan 1.3** | **Yes** (Vulkan 1.3) | **CUDA 12.8+** | NVK added full Ada support recently. Proprietary driver still required if hardware Ray Tracing or DLSS 3 (Frame Generation) is needed, as NVK does not yet implement these proprietary extensions. |
| **Blackwell**<br>*(GB100/102/202)* | [570](https://docs.nvidia.com/datacenter/tesla/tesla-release-notes-570-211-01/index.html) to 610+ | `nvidia` (**Open Module**) | **Vulkan 1.3** | **Yes** (In development) | **CUDA 12.8+** | Latest generation architecture (RTX 5090/5080). NVK support is landing in the most recent kernel versions (6.12+) and Mesa (24.3+). Requires very updated `linux-firmware`. |
| **Blackwell**<br>*(GB100/102/202)* | [570.xx](https://docs.nvidia.com/datacenter/tesla/tesla-release-notes-570-211-01/index.html) to 610+ | `nvidia` (**Open Module**) | **Vulkan 1.3** | **Yes** (In development) | **CUDA 12.8+** | Latest generation architecture (RTX 5090/5080). NVK support is landing in the most recent kernel versions (6.12+) and Mesa (24.3+). Requires very updated `linux-firmware`. |
#### 💡 Quick context glossary for documentation:
* **Open Module:** Starting with driver 515, [NVIDIA releases code that interacts directly with the Linux kernel under MIT/GPL license](https://developer.nvidia.com/blog/nvidia-releases-open-source-gpu-kernel-modules/). However, the GPU still requires loading a proprietary closed microcode called **GSP (GPU System Processor)** to boot.
@@ -153,8 +155,8 @@ When the script detects Intel or AMD hardware, it triggers a specific installati
| Vendor | Kernel Driver (KMD) | Mesa User-Space Driver | VAAPI Backend Strategy |
| :--- | :--- | :--- | :--- |
| **Intel Gen < 8** | `i915` | `crocus` / `iris` | Installs `i965-va-driver-shaders`. Legacy path for older CPUs. |
| **Intel Gen 8+** | `i915` | `iris` / `anv` | Installs `intel-media-va-driver-non-free`. Modern, preferred backend for Broadwell+. |
| **Intel Gen < 8** | `i915` | `crocus` / `iris` | Installs [`i965-va-driver-shaders`](https://github.com/intel/intel-vaapi-driver/). Legacy path for older CPUs. |
| **Intel Gen 8+** | `i915` | `iris` / `anv` | Installs [`intel-media-va-driver-non-free](https://github.com/intel/media-driver). Modern, preferred backend for Broadwell+. |
| **AMD GCN/RDNA** | `amdgpu` | `radeonsi` (GL) + `RADV` (VK) | Uses standard `va-driver-all`. Requires kernel param tuning for older GCN. |
**Critical Consistency Check:**
+8
View File
@@ -241,3 +241,11 @@ To ensure ZRAM persists across reboots, the script writes configuration to `/etc
```bash
echo "zram" | sudo tee /etc/modules-load.d/zram.conf
```
### References:
- [https://docs.kernel.org/admin-guide/blockdev/zram.html](https://docs.kernel.org/admin-guide/blockdev/zram.html)
- [https://wiki.debian.org/ZRam](https://wiki.debian.org/ZRam)
- [https://wiki.archlinux.org/title/Zram](https://wiki.archlinux.org/title/Zram)
- [https://wiki.gentoo.org/wiki/Zram](https://wiki.gentoo.org/wiki/Zram)
+2 -2
View File
@@ -19,7 +19,7 @@ _install_bluetooth_stack() {
return
fi
if is_installed bluez && is_installed bluez-utils; then
if is_installed bluez; then
echo " → Bluetooth stack already installed."
service_enable_only=true
fi
@@ -27,7 +27,7 @@ _install_bluetooth_stack() {
if [ ! ${service_enable_only:-false} = true ]; then
local bt_pkgs=()
! is_installed bluez && bt_pkgs+=(bluez)
! is_installed bluez-utils && bt_pkgs+=(bluez-utils)
! is_installed bluez-tools && bt_pkgs+=(bluez-tools)
! is_installed bluez-obexd && bt_pkgs+=(bluez-obexd)
if [ ${#bt_pkgs[@]} -gt 0 ]; then
_run_cmd "Bluetooth" "sudo DEBIAN_FRONTEND=noninteractive apt install -y ${bt_pkgs[*]}" "Installing Bluetooth stack..."
+185 -172
View File
@@ -58,15 +58,13 @@ Instalar?"; then
# ======================================================================
_cat_customization_bullseye() {
local TUI_ANCHO_REFORZADO=$((TUI_ANCHO + 6))
local sub
sub=$(whiptail --title "Customization (Bullseye)" --menu \
"Select type:" $TUI_ALTO $TUI_ANCHO_REFORZADO $TUI_ALTO_LISTA \
sub=$(_menu "Customization (Bullseye)" "Select type:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
"1" "Desktop Themes (GTK/KDE)" \
"2" "Icon Themes" \
"3" "Cursor Themes" \
"4" "Fonts" \
3>&1 1>&2 2>&3)
)
[ -z "$sub" ] && return
case $sub in
1) _cat_themes_bullseye ;;
@@ -77,16 +75,17 @@ _cat_customization_bullseye() {
}
_cat_themes_bullseye() {
local item_count=6
local lista_alto=$((item_count > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count))
local choices
choices=$(whiptail --title "Desktop Themes (Bullseye)" --checklist \
"Select desktop themes${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
"arc-theme" "Arc GTK theme$(_inst arc-theme)" "$(_state arc-theme)" \
"blackbird-gtk-theme" "Blackbird GTK theme$(_inst blackbird-gtk-theme)" "$(_state blackbird-gtk-theme)" \
"bluebird-gtk-theme" "Bluebird GTK theme$(_inst bluebird-gtk-theme)" "$(_state bluebird-gtk-theme)" \
"breeze-gtk-theme" "Breeze GTK theme (KDE port)$(_inst breeze-gtk-theme)" "$(_state breeze-gtk-theme)" \
"greybird-gtk-theme" "Greybird GTK theme$(_inst greybird-gtk-theme)" "$(_state greybird-gtk-theme)" \
"numix-gtk-theme" "Numix GTK theme$(_inst numix-gtk-theme)" "$(_state numix-gtk-theme)" \
3>&1 1>&2 2>&3)
choices=$(_checklist "Desktop Themes (Bullseye)" "Select desktop themes${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $lista_alto \
"arc-theme" "Arc GTK theme" "$(_state arc-theme)" \
"blackbird-gtk-theme" "Blackbird GTK theme" "$(_state blackbird-gtk-theme)" \
"bluebird-gtk-theme" "Bluebird GTK theme" "$(_state bluebird-gtk-theme)" \
"breeze-gtk-theme" "Breeze GTK theme (KDE port)" "$(_state breeze-gtk-theme)" \
"greybird-gtk-theme" "Greybird GTK theme" "$(_state greybird-gtk-theme)" \
"numix-gtk-theme" "Numix GTK theme" "$(_state numix-gtk-theme)" \
)
clear
[ -z "$choices" ] && return
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
@@ -98,20 +97,21 @@ _cat_themes_bullseye() {
_cat_icons_bullseye() {
local items=(
"breeze-icon-theme" "Breeze icon theme$(_inst breeze-icon-theme)" "$(_state breeze-icon-theme)"
"deepin-icon-theme" "Deepin icon theme$(_inst deepin-icon-theme)" "$(_state deepin-icon-theme)"
"moka-icon-theme" "Moka icon theme$(_inst moka-icon-theme)" "$(_state moka-icon-theme)"
"numix-icon-theme" "Numix icon theme$(_inst numix-icon-theme)" "$(_state numix-icon-theme)"
"numix-icon-theme-circle" "Numix Circle icon theme$(_inst numix-icon-theme-circle)" "$(_state numix-icon-theme-circle)"
"obsidian-icon-theme" "Obsidian icon theme$(_inst obsidian-icon-theme)" "$(_state obsidian-icon-theme)"
"papirus-icon-theme" "Papirus icon theme$(_inst papirus-icon-theme)" "$(_state papirus-icon-theme)"
"paper-icon-theme" "Paper icon theme$(_inst paper-icon-theme)" "$(_state paper-icon-theme)"
"suru-icon-theme" "Suru icon theme$(_inst suru-icon-theme)" "$(_state suru-icon-theme)"
"breeze-icon-theme" "Breeze icon theme" "$(_state breeze-icon-theme)"
"deepin-icon-theme" "Deepin icon theme" "$(_state deepin-icon-theme)"
"moka-icon-theme" "Moka icon theme" "$(_state moka-icon-theme)"
"numix-icon-theme" "Numix icon theme" "$(_state numix-icon-theme)"
"numix-icon-theme-circle" "Numix Circle icon theme" "$(_state numix-icon-theme-circle)"
"obsidian-icon-theme" "Obsidian icon theme" "$(_state obsidian-icon-theme)"
"papirus-icon-theme" "Papirus icon theme" "$(_state papirus-icon-theme)"
"paper-icon-theme" "Paper icon theme" "$(_state paper-icon-theme)"
"suru-icon-theme" "Suru icon theme" "$(_state suru-icon-theme)"
)
local item_count=${#items[@]}
local lista_alto=$((item_count > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count))
local choices
choices=$(whiptail --title "Icon Themes (Bullseye)" --checklist \
"Select icon themes${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
"${items[@]}" 3>&1 1>&2 2>&3)
choices=$(_checklist "Icon Themes (Bullseye)" "Select icon themes${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $lista_alto \
"${items[@]}" )
clear
[ -z "$choices" ] && return
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
@@ -122,15 +122,16 @@ _cat_icons_bullseye() {
}
_cat_cursors_bullseye() {
local item_count=5
local lista_alto=$((item_count > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count))
local choices
choices=$(whiptail --title "Cursor Themes (Bullseye)" --checklist \
"Select cursor themes${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
"breeze-cursor-theme" "Breeze cursors (KDE)$(_inst breeze-cursor-theme)" "$(_state breeze-cursor-theme)" \
"chameleon-cursor-theme" "Chameleon cursors$(_inst chameleon-cursor-theme)" "$(_state chameleon-cursor-theme)" \
"dmz-cursor-theme" "DMZ cursors$(_inst dmz-cursor-theme)" "$(_state dmz-cursor-theme)" \
"oxygencursors" "Oxygen cursors (KDE legacy)$(_inst oxygencursors)" "$(_state oxygencursors)" \
"xcursor-themes" "X11 base cursors$(_inst xcursor-themes)" "$(_state xcursor-themes)" \
3>&1 1>&2 2>&3)
choices=$(_checklist "Cursor Themes (Bullseye)" "Select cursor themes${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $lista_alto \
"breeze-cursor-theme" "Breeze cursors (KDE)" "$(_state breeze-cursor-theme)" \
"chameleon-cursor-theme" "Chameleon cursors" "$(_state chameleon-cursor-theme)" \
"dmz-cursor-theme" "DMZ cursors" "$(_state dmz-cursor-theme)" \
"oxygencursors" "Oxygen cursors (KDE legacy)" "$(_state oxygencursors)" \
"xcursor-themes" "X11 base cursors" "$(_state xcursor-themes)" \
)
clear
[ -z "$choices" ] && return
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
@@ -141,14 +142,15 @@ _cat_cursors_bullseye() {
}
_cat_fonts_bullseye() {
local item_count=4
local lista_alto=$((item_count > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count))
local choices
choices=$(whiptail --title "Fonts (Bullseye)" --checklist \
"Available fonts${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
"fonts-firacode" "Fira Code monospace font$(_inst fonts-firacode)" "$(_state fonts-firacode)" \
"fonts-noto" "Noto fonts (Google)$(_inst fonts-noto)" "$(_state fonts-noto)" \
"fonts-dejavu-core" "DejaVu core fonts$(_inst fonts-dejavu-core)" "$(_state fonts-dejavu-core)" \
"ttf-mscorefonts-installer" "Microsoft Core Fonts$(_inst ttf-mscorefonts-installer)" "$(_state ttf-mscorefonts-installer)" \
3>&1 1>&2 2>&3)
choices=$(_checklist "Fonts (Bullseye)" "Available fonts${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $lista_alto \
"fonts-firacode" "Fira Code monospace font" "$(_state fonts-firacode)" \
"fonts-noto" "Noto fonts (Google)" "$(_state fonts-noto)" \
"fonts-dejavu-core" "DejaVu core fonts" "$(_state fonts-dejavu-core)" \
"ttf-mscorefonts-installer" "Microsoft Core Fonts" "$(_state ttf-mscorefonts-installer)" \
)
clear
[ -z "$choices" ] && return
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
@@ -161,24 +163,26 @@ _cat_fonts_bullseye() {
_cat_download_bullseye() {
local choices1 choices2=""
choices1=$(whiptail --title "Downloaders" --checklist \
"Select download tools:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
"aria2" "Multiprotocol downloader (CLI)$(_inst aria2)" "$(_state aria2)" \
"filezilla" "FTP/SFTP client (GUI)$(_inst filezilla)" "$(_state filezilla)" \
3>&1 1>&2 2>&3)
local item_count1=2
local lista_alto1=$((item_count1 > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count1))
choices1=$(_checklist "Downloaders" "Select download tools:" $TUI_ALTO $TUI_ANCHO $lista_alto1 \
"aria2" "Multiprotocol downloader (CLI)" "$(_state aria2)" \
"filezilla" "FTP/SFTP client (GUI)" "$(_state filezilla)" \
)
clear
choices2=$(whiptail --title "Torrent Clients" --checklist \
"Select torrent clients${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
"deluge" "BitTorrent client (GTK)$(_inst deluge)" "$(_state deluge)" \
"deluged" "BitTorrent daemon/server$(_inst deluged)" "$(_state deluged)" \
"mktorrent" "Torrent metainfo creator (CLI)$(_inst mktorrent)" "$(_state mktorrent)" \
"qbittorrent" "BitTorrent client (Qt)$(_inst qbittorrent)" "$(_state qbittorrent)" \
"qbittorrent-nox" "BitTorrent WebUI/CLI$(_inst qbittorrent-nox)" "$(_state qbittorrent-nox)" \
"transmission-cli" "BitTorrent client (CLI)$(_inst transmission-cli)" "$(_state transmission-cli)" \
"transmission-gtk" "BitTorrent client (GTK)$(_inst transmission-gtk)" "$(_state transmission-gtk)" \
"transmission-qt" "BitTorrent client (Qt)$(_inst transmission-qt)" "$(_state transmission-qt)" \
3>&1 1>&2 2>&3)
local item_count2=8
local lista_alto2=$((item_count2 > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count2))
choices2=$(_checklist "Torrent Clients" "Select torrent clients${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $lista_alto2 \
"deluge" "BitTorrent client (GTK)" "$(_state deluge)" \
"deluged" "BitTorrent daemon/server" "$(_state deluged)" \
"mktorrent" "Torrent metainfo creator (CLI)" "$(_state mktorrent)" \
"qbittorrent" "BitTorrent client (Qt)" "$(_state qbittorrent)" \
"qbittorrent-nox" "BitTorrent WebUI/CLI" "$(_state qbittorrent-nox)" \
"transmission-cli" "BitTorrent client (CLI)" "$(_state transmission-cli)" \
"transmission-gtk" "BitTorrent client (GTK)" "$(_state transmission-gtk)" \
"transmission-qt" "BitTorrent client (Qt)" "$(_state transmission-qt)" \
)
clear
local cleaned
@@ -196,21 +200,22 @@ _cat_download_bullseye() {
}
_cat_internet_bullseye() {
local item_count=11
local lista_alto=$((item_count > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count))
local choices
choices=$(whiptail --title "Internet (Bullseye)" --checklist \
"Select browsers, email${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
"chromium" "Chromium web browser$(_inst chromium)" "$(_state chromium)" \
"dillo" "Lightweight graphical browser$(_inst dillo)" "$(_state dillo)" \
"elinks" "Text-mode web browser$(_inst elinks)" "$(_state elinks)" \
"epiphany-browser" "GNOME web browser$(_inst epiphany-browser)" "$(_state epiphany-browser)" \
"falkon" "KDE web browser (QtWebEngine)$(_inst falkon)" "$(_state falkon)" \
"firefox-esr" "Firefox ESR (official Debian)$(_inst firefox-esr)" "$(_state firefox-esr)" \
"konqueror" "KDE file manager / web browser$(_inst konqueror)" "$(_state konqueror)" \
"qutebrowser" "Keyboard-driven browser (Qt)$(_inst qutebrowser)" "$(_state qutebrowser)" \
"thunderbird" "Email client$(_inst thunderbird)" "$(_state thunderbird)" \
"torbrowser-launcher" "Tor Browser launcher$(_inst torbrowser-launcher)" "$(_state torbrowser-launcher)" \
"w3m" "Text-mode browser + deps$(_inst w3m)" "$(_state w3m)" \
3>&1 1>&2 2>&3)
choices=$(_checklist "Internet (Bullseye)" "Select browsers, email${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $lista_alto \
"chromium" "Chromium web browser" "$(_state chromium)" \
"dillo" "Lightweight graphical browser" "$(_state dillo)" \
"elinks" "Text-mode web browser" "$(_state elinks)" \
"epiphany-browser" "GNOME web browser" "$(_state epiphany-browser)" \
"falkon" "KDE web browser (QtWebEngine)" "$(_state falkon)" \
"firefox-esr" "Firefox ESR (official Debian)" "$(_state firefox-esr)" \
"konqueror" "KDE file manager / web browser" "$(_state konqueror)" \
"qutebrowser" "Keyboard-driven browser (Qt)" "$(_state qutebrowser)" \
"thunderbird" "Email client" "$(_state thunderbird)" \
"torbrowser-launcher" "Tor Browser launcher" "$(_state torbrowser-launcher)" \
"w3m" "Text-mode browser + deps" "$(_state w3m)" \
)
clear
[ -z "$choices" ] && return
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
@@ -237,12 +242,13 @@ _cat_internet_bullseye() {
}
_cat_players_bullseye() {
local item_count=2
local lista_alto=$((item_count > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count))
local choices
choices=$(whiptail --title "Media Players (Bullseye)" --checklist \
"Select media players${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
"mpv" "Lightweight media player$(_inst mpv)" "$(_state mpv)" \
"vlc" "VLC media player$(_inst vlc)" "$(_state vlc)" \
3>&1 1>&2 2>&3)
choices=$(_checklist "Media Players (Bullseye)" "Select media players${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $lista_alto \
"mpv" "Lightweight media player" "$(_state mpv)" \
"vlc" "VLC media player" "$(_state vlc)" \
)
clear
[ -z "$choices" ] && return
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
@@ -257,23 +263,24 @@ _cat_players_bullseye() {
}
_cat_design_bullseye() {
local item_count=13
local lista_alto=$((item_count > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count))
local choices
choices=$(whiptail --title "Multimedia & Design (Bullseye)" --checklist \
"Select multimedia and design tools${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
"ardour" "Digital audio workstation$(_inst ardour)" "$(_state ardour)" \
"audacity" "Audio editor/recorder$(_inst audacity)" "$(_state audacity)" \
"blender" "3D modeling/animation suite$(_inst blender)" "$(_state blender)" \
"ffmpeg" "Multimedia framework (CLI)$(_inst ffmpeg)" "$(_state ffmpeg)" \
"gimp" "Image editor$(_inst gimp)" "$(_state gimp)" \
"handbrake" "Video transcoder (DVD ripper)$(_inst handbrake)" "$(_state handbrake)" \
"inkscape" "Vector graphics editor$(_inst inkscape)" "$(_state inkscape)" \
"kdenlive" "Video editor (KDE)$(_inst kdenlive)" "$(_state kdenlive)" \
"krita" "Digital painting/illustration$(_inst krita)" "$(_state krita)" \
"obs-studio" "Screen recording/streaming$(_inst obs-studio)" "$(_state obs-studio)" \
"openshot-qt" "Video editor (simple)$(_inst openshot-qt)" "$(_state openshot-qt)" \
"scribus" "Desktop publishing (DTP)$(_inst scribus)" "$(_state scribus)" \
"shotcut" "Video editor (cross-platform)$(_inst shotcut)" "$(_state shotcut)" \
3>&1 1>&2 2>&3)
choices=$(_checklist "Multimedia & Design (Bullseye)" "Select multimedia and design tools${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $lista_alto \
"ardour" "Digital audio workstation" "$(_state ardour)" \
"audacity" "Audio editor/recorder" "$(_state audacity)" \
"blender" "3D modeling/animation suite" "$(_state blender)" \
"ffmpeg" "Multimedia framework (CLI)" "$(_state ffmpeg)" \
"gimp" "Image editor" "$(_state gimp)" \
"handbrake" "Video transcoder (DVD ripper)" "$(_state handbrake)" \
"inkscape" "Vector graphics editor" "$(_state inkscape)" \
"kdenlive" "Video editor (KDE)" "$(_state kdenlive)" \
"krita" "Digital painting/illustration" "$(_state krita)" \
"obs-studio" "Screen recording/streaming" "$(_state obs-studio)" \
"openshot-qt" "Video editor (simple)" "$(_state openshot-qt)" \
"scribus" "Desktop publishing (DTP)" "$(_state scribus)" \
"shotcut" "Video editor (cross-platform)" "$(_state shotcut)" \
)
clear
[ -z "$choices" ] && return
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
@@ -288,19 +295,20 @@ _cat_design_bullseye() {
}
_cat_programming_bullseye() {
local item_count=9
local lista_alto=$((item_count > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count))
local choices
choices=$(whiptail --title "Code Editors & IDEs (Bullseye)" --checklist \
"Select editors and IDEs${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
"vim" "Classic terminal editor$(_inst vim)" "$(_state vim)" \
"vim-gtk3" "Vim with GTK3 GUI$(_inst vim-gtk3)" "$(_state vim-gtk3)" \
"neovim" "Modern vim fork$(_inst neovim)" "$(_state neovim)" \
"nano" "Simple terminal editor$(_inst nano)" "$(_state nano)" \
"emacs" "Extensible editor / IDE$(_inst emacs)" "$(_state emacs)" \
"kate" "KDE advanced text editor$(_inst kate)" "$(_state kate)" \
"mousepad" "Xfce text editor$(_inst mousepad)" "$(_state mousepad)" \
"gedit" "GNOME text editor$(_inst gedit)" "$(_state gedit)" \
"geany" "Lightweight IDE$(_inst geany)" "$(_state geany)" \
3>&1 1>&2 2>&3)
choices=$(_checklist "Code Editors & IDEs (Bullseye)" "Select editors and IDEs${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $lista_alto \
"vim" "Classic terminal editor" "$(_state vim)" \
"vim-gtk3" "Vim with GTK3 GUI" "$(_state vim-gtk3)" \
"neovim" "Modern vim fork" "$(_state neovim)" \
"nano" "Simple terminal editor" "$(_state nano)" \
"emacs" "Extensible editor / IDE" "$(_state emacs)" \
"kate" "KDE advanced text editor" "$(_state kate)" \
"mousepad" "Xfce text editor" "$(_state mousepad)" \
"gedit" "GNOME text editor" "$(_state gedit)" \
"geany" "Lightweight IDE" "$(_state geany)" \
)
clear
[ -z "$choices" ] && return
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
@@ -315,24 +323,25 @@ _cat_programming_bullseye() {
}
_cat_dev_bullseye() {
local item_count=14
local lista_alto=$((item_count > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count))
local choices
choices=$(whiptail --title "Servers & Dev Tools (Bullseye)" --checklist \
"Select development tools and servers${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
"apache2" "Apache web server$(_inst apache2)" "$(_state apache2)" \
"build-essential" "C/C++ build tools (gcc, make)$(_inst build-essential)" "$(_state build-essential)" \
"docker" "Docker container runtime$(_inst docker.io)" "$(_state docker.io)" \
"mariadb-server" "MariaDB database server$(_inst mariadb-server)" "$(_state mariadb-server)" \
"netcat-openbsd" "TCP/IP networking utility$(_inst netcat-openbsd)" "$(_state netcat-openbsd)" \
"nginx" "Nginx web server$(_inst nginx)" "$(_state nginx)" \
"openssh-server" "SSH server$(_inst openssh-server)" "$(_state openssh-server)" \
"openssl" "OpenSSL cryptography toolkit$(_inst openssl)" "$(_state openssl)" \
"postgresql" "PostgreSQL database server$(_inst postgresql)" "$(_state postgresql)" \
"python3-pip" "Python 3 pip + venv + dev$(_inst python3-pip)" "$(_state python3-pip)" \
"redis-server" "Redis key-value store$(_inst redis-server)" "$(_state redis-server)" \
"sqlite3" "SQLite database engine$(_inst sqlite3)" "$(_state sqlite3)" \
"jellyfin" "Jellyfin Media Server (Web GUI on port 8096)$(_inst jellyfin)" OFF \
choices=$(_checklist "Servers & Dev Tools (Bullseye)" "Select development tools and servers${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $lista_alto \
"apache2" "Apache web server" "$(_state apache2)" \
"build-essential" "C/C++ build tools (gcc, make)" "$(_state build-essential)" \
"docker" "Docker container runtime" "$(_state docker.io)" \
"mariadb-server" "MariaDB database server" "$(_state mariadb-server)" \
"netcat-openbsd" "TCP/IP networking utility" "$(_state netcat-openbsd)" \
"nginx" "Nginx web server" "$(_state nginx)" \
"openssh-server" "SSH server" "$(_state openssh-server)" \
"openssl" "OpenSSL cryptography toolkit" "$(_state openssl)" \
"postgresql" "PostgreSQL database server" "$(_state postgresql)" \
"python3-pip" "Python 3 pip + venv + dev" "$(_state python3-pip)" \
"redis-server" "Redis key-value store" "$(_state redis-server)" \
"sqlite3" "SQLite database engine" "$(_state sqlite3)" \
"jellyfin" "Jellyfin Media Server (Web GUI on port 8096)" OFF \
"openjdk-dev-env" "Adoptium Temurin JDK (17, 21, 25 LTS)$(_any_jdk_installed_desc)" "$(_any_jdk_state)" \
3>&1 1>&2 2>&3)
)
clear
[ -z "$choices" ] && return
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
@@ -378,15 +387,16 @@ _cat_dev_bullseye() {
echo -e "${GREEN}Servers & dev tools installed.${NC}"
}
_cat_security_bullseye() {
local item_count=5
local lista_alto=$((item_count > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count))
local choices
choices=$(whiptail --title "Security & Networking (Bullseye)" --checklist \
"Select security and networking tools${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
"wireshark" "Network protocol analyzer (GUI)$(_inst wireshark)" "$(_state wireshark)" \
"tcpdump" "Command-line packet analyzer$(_inst tcpdump)" "$(_state tcpdump)" \
"fail2ban" "Brute-force protection daemon$(_inst fail2ban)" "$(_state fail2ban)" \
"ufw" "Uncomplicated firewall$(_inst ufw)" "$(_state ufw)" \
"clamav" "Antivirus engine (ClamAV)$(_inst clamav)" "$(_state clamav)" \
3>&1 1>&2 2>&3)
choices=$(_checklist "Security & Networking (Bullseye)" "Select security and networking tools${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $lista_alto \
"wireshark" "Network protocol analyzer (GUI)" "$(_state wireshark)" \
"tcpdump" "Command-line packet analyzer" "$(_state tcpdump)" \
"fail2ban" "Brute-force protection daemon" "$(_state fail2ban)" \
"ufw" "Uncomplicated firewall" "$(_state ufw)" \
"clamav" "Antivirus engine (ClamAV)" "$(_state clamav)" \
)
clear
[ -z "$choices" ] && return
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
@@ -408,29 +418,30 @@ _cat_security_bullseye() {
}
_cat_general_bullseye() {
local item_count=18
local lista_alto=$((item_count > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count))
local choices
choices=$(whiptail --title "System Tools (Bullseye)" --checklist \
"Select system utilities${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
"compress" "Compression tools (zip, unrar, p7zip)$(_inst zip)" "$(_state zip)" \
"conky" "System monitor for desktop$(_inst conky)" "$(_state conky)" \
"cpu-x" "CPU-X (alternative to CPU-Z)$(_inst cpu-x)" "$(_state cpu-x)" \
"curl-wget" "HTTP transfer tools (curl, wget)$(_inst curl)" "$(_state curl)" \
"flatpak" "Flatpak sandbox (Bullseye native)$(_inst flatpak)" "$(_state flatpak)" \
"fwupd" "Firmware update daemon$(_inst fwupd)" "$(_state fwupd)" \
"gnome-disk-utility" "Disk management GUI$(_inst gnome-disk-utility)" "$(_state gnome-disk-utility)" \
"gparted" "Partition editor$(_inst gparted)" "$(_state gparted)" \
"htop" "Interactive process viewer$(_inst htop)" "$(_state htop)" \
"inxi" "System information tool$(_inst inxi)" "$(_state inxi)" \
"kvm" "QEMU/KVM virtualization$(_inst virt-manager)" "$(_state virt-manager)" \
"lshw" "List hardware details$(_inst lshw)" "$(_state lshw)" \
"mc" "Midnight Commander$(_inst mc)" "$(_state mc)" \
"nvme-cli" "NVMe SSD health monitoring$(_inst nvme-cli)" "$(_state nvme-cli)" \
"ncdu" "Disk usage analyzer$(_inst ncdu)" "$(_state ncdu)" \
"psensor" "Temperature monitor$(_inst psensor)" "$(_state psensor)" \
"timeshift" "System restore snapshots$(_inst timeshift)" "$(_state timeshift)" \
"tmux" "Terminal multiplexer$(_inst tmux)" "$(_state tmux)" \
"wine" "Windows compatibility layer$(_inst wine)" "$(_state wine)" \
3>&1 1>&2 2>&3)
choices=$(_checklist "System Tools (Bullseye)" "Select system utilities${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $lista_alto \
"compress" "Compression tools (zip, unrar, p7zip)" "$(_state zip)" \
"conky" "System monitor for desktop" "$(_state conky)" \
"cpu-x" "CPU-X (alternative to CPU-Z)" "$(_state cpu-x)" \
"curl-wget" "HTTP transfer tools (curl, wget)" "$(_state curl)" \
"flatpak" "Flatpak sandbox (Bullseye native)" "$(_state flatpak)" \
"fwupd" "Firmware update daemon" "$(_state fwupd)" \
"gnome-disk-utility" "Disk management GUI" "$(_state gnome-disk-utility)" \
"gparted" "Partition editor" "$(_state gparted)" \
"htop" "Interactive process viewer" "$(_state htop)" \
"inxi" "System information tool" "$(_state inxi)" \
"kvm" "QEMU/KVM virtualization" "$(_state virt-manager)" \
"lshw" "List hardware details" "$(_state lshw)" \
"mc" "Midnight Commander" "$(_state mc)" \
"nvme-cli" "NVMe SSD health monitoring" "$(_state nvme-cli)" \
"ncdu" "Disk usage analyzer" "$(_state ncdu)" \
"psensor" "Temperature monitor" "$(_state psensor)" \
"timeshift" "System restore snapshots" "$(_state timeshift)" \
"tmux" "Terminal multiplexer" "$(_state tmux)" \
"wine" "Windows compatibility layer" "$(_state wine)" \
)
clear
[ -z "$choices" ] && return
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
@@ -472,15 +483,17 @@ _cat_general_bullseye() {
fi
;;
wine)
if ! is_installed "wine"; then
if ! dpkg --print-foreign-architectures 2>/dev/null | grep -q i386; then
sudo dpkg --add-architecture i386
_run_cmd "APT Update" "sudo apt update" "Updating package lists..."
fi
_run_cmd "Wine" "sudo apt install -y wine wine32 wine64 libwine libwine:i386 fonts-wine" "Installing Wine..."
echo -e "${GREEN}Wine installed.${NC}"
if ! is_installed "wine64"; then
_run_cmd "Wine" "sudo apt install -y --no-install-recommends wine64 fonts-wine" "Installing Wine (64-bit only)..."
local wine_ver
wine_ver=$(wine --version 2>/dev/null)
if [ -n "$wine_ver" ]; then
echo -e "${GREEN}Wine (64-bit) installed: ${wine_ver}${NC}"
else
echo "Wine already installed."
echo -e "${YELLOW}Wine installed but version check failed.${NC}"
fi
else
echo "Wine64 already installed."
fi
;;
fwupd)
@@ -490,6 +503,7 @@ _cat_general_bullseye() {
if _confirm "Firmware Scan" "Scan for firmware updates now?"; then
sudo fwupdmgr refresh --force 2>/dev/null || true
sudo fwupdmgr get-updates 2>&1 || true
_pause
fi
;;
nvme-cli)
@@ -505,19 +519,20 @@ _cat_general_bullseye() {
esac
done
echo -e "${GREEN}System tools installed.${NC}"
_pause
}
_cat_fetch_bullseye() {
local items=(
"neofetch" "System info fetcher$(_inst neofetch)" "$(_state neofetch)"
"screenfetch" "System info (BSD/Linux)$(_inst screenfetch)" "$(_state screenfetch)"
"linuxlogo" "Linux logo + system info$(_inst linuxlogo)" "$(_state linuxlogo)"
"neofetch" "System info fetcher" "$(_state neofetch)"
"screenfetch" "System info (BSD/Linux)" "$(_state screenfetch)"
"linuxlogo" "Linux logo + system info" "$(_state linuxlogo)"
)
local TUI_ANCHO_REFORZADO=$((TUI_ANCHO + 6))
local item_count=${#items[@]}
local lista_alto=$((item_count > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count))
local choices
choices=$(whiptail --title "Fetch Tools (Bullseye)" --checklist \
"Select system info tools:" $TUI_ALTO $TUI_ANCHO_REFORZADO $TUI_ALTO_LISTA \
"${items[@]}" 3>&1 1>&2 2>&3)
choices=$(_checklist "Fetch Tools (Bullseye)" "Select system info tools:" $TUI_ALTO $TUI_ANCHO $lista_alto \
"${items[@]}" )
clear
[ -z "$choices" ] && return
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
@@ -540,8 +555,7 @@ install_extras_bullseye() {
while true; do
local cat_choice
cat_choice=$(whiptail --title "Extra Software — Bullseye" --menu \
"Select a category${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
cat_choice=$(_menu "Extra Software — Bullseye" "Select a category${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
"0" "Essential Pack" \
"1" "Customization System" \
"2" "Download & Network" \
@@ -555,7 +569,7 @@ install_extras_bullseye() {
"10" "System Tools" \
"11" "Fetch / System Info" \
"12" "Back to main menu" \
3>&1 1>&2 2>&3)
)
[ -z "$cat_choice" ] && return
clear
@@ -581,11 +595,10 @@ install_extras_bullseye() {
_cat_software_centers_bullseye() {
local sc_choice
sc_choice=$(whiptail --title "Software Centers" --menu \
"Choose a software store to install:" 12 65 2 \
"gnome-software" "Software Center for GNOME$(_inst gnome-software)" \
"plasma-discover" "Software manager for Plasma$(_inst plasma-discover)" \
3>&1 1>&2 2>&3)
sc_choice=$(_menu "Software Centers" "Choose a software store to install:" 12 65 2 \
"gnome-software" "Software Center for GNOME" \
"plasma-discover" "Software manager for Plasma" \
)
[ -z "$sc_choice" ] && return
_run_cmd "Install" "sudo apt install -y $sc_choice" "Installing ${sc_choice}..."
+14 -29
View File
@@ -27,28 +27,6 @@ No security updates will be available." 12 60
fi
}
# ---------------------------------------------------------------------------
# Fermi PCI ID detection — 6 condiciones inclusivas
# ---------------------------------------------------------------------------
is_nvidia_fermi() {
local dev_id
dev_id=$(lspci -nn | grep -iE "VGA|3D" | grep -i nvidia | \
grep -oP '10de:\K[0-9a-fA-F]+' | head -n1)
[ -z "$dev_id" ] && { echo false; return; }
local dev_int
dev_int=$((16#${dev_id,,}))
if [ "$dev_int" -ge $((16#06C0)) ] && [ "$dev_int" -le $((16#06DF)) ]; then echo true; return; fi
if [ "$dev_int" -ge $((16#0DC0)) ] && [ "$dev_int" -le $((16#0DFF)) ]; then echo true; return; fi
if [ "$dev_int" -ge $((16#0DE0)) ] && [ "$dev_int" -le $((16#0DFF)) ]; then echo true; return; fi
if [ "$dev_int" -ge $((16#0E00)) ] && [ "$dev_int" -le $((16#0E1F)) ]; then echo true; return; fi
if [ "$dev_int" -ge $((16#1080)) ] && [ "$dev_int" -le $((16#10DF)) ]; then echo true; return; fi
if [ "$dev_int" -eq $((16#1201)) ]; then echo true; return; fi
echo false
}
# ---------------------------------------------------------------------------
# NVIDIA driver installer for Bullseye (Kepler → 470, Fermi → 390)
# ---------------------------------------------------------------------------
@@ -186,17 +164,17 @@ Installs matching 32-bit graphics drivers."; then
# Gaming tools checklist (no Steam, no Heroic)
local choices
choices=$(whiptail --title "Gaming Tools — Bullseye" --checklist \
choices=$(_checklist "Gaming Tools — Bullseye" \
"Select gaming optimization tools:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
"gamemode" "Game performance optimization" ON \
"mangohud" "Performance overlay (Vulkan/OpenGL)" ON \
"goverlay" "MangoHud config GUI" ON \
"lutris" "Game launcher/manager" OFF \
"java" "Java Runtimes (8, 17, 21)" OFF \
3>&1 1>&2 2>&3)
"java" "Java Runtimes (8, 17, 21)" OFF)
if [ -z "$choices" ]; then
echo "No gaming tools selected."
_pause
return
fi
@@ -206,24 +184,31 @@ Installs matching 32-bit graphics drivers."; then
for pkg in $cleaned; do
case $pkg in
mangohud)
_run_cmd "MangoHud" "sudo apt install -y mangohud" "Installing MangoHud..."
local mh_pkgs="mangohud"
if $enable_32bit; then
local mh32_ver
mh32_ver=$(apt-cache policy mangohud:i386 2>/dev/null | \
awk 'NR==3 {print $2; exit}')
if [ -n "$mh32_ver" ] && [ "$mh32_ver" != "(none)" ]; then
_run_cmd "MangoHud" "sudo apt install -y mangohud:i386" \
"Installing MangoHud 32-bit..."
mh_pkgs+=" mangohud:i386"
fi
fi
_run_cmd "MangoHud" "sudo apt install -y $mh_pkgs" "Installing MangoHud (64 + 32-bit)..."
;;
gamemode) _run_cmd "GameMode" "sudo apt install -y gamemode" "Installing GameMode..." ;;
goverlay) _run_cmd "GOverlay" "sudo apt install -y goverlay" "Installing GOverlay..." ;;
lutris) _run_cmd "Lutris" "sudo apt install -y lutris" "Installing Lutris..." ;;
lutris)
local pkgs="lutris wine64"
if dpkg --print-foreign-architectures 2>/dev/null | grep -q i386; then
pkgs+=" wine32"
fi
_run_cmd "Lutris" "sudo apt install -y $pkgs" "Installing Lutris + Wine..."
;;
java) _install_gaming_java ;;
*) _run_install "$pkg" ;;
esac
done
echo -e "${GREEN}Lightweight gaming setup complete.${NC}"
_pause
}
+79
View File
@@ -0,0 +1,79 @@
#!/usr/bin/env bash
manage_desktop_display() {
while true; do
local choice
choice=$(_menu "Desktop & Display" \
"Select an option:" $TUI_ALTO $TUI_ANCHO 6 \
"1" "Desktop Environment" \
"2" "Display Manager" \
"3" "Back to main menu")
[ -z "$choice" ] && break
clear
case "$choice" in
1) _msg "Coming Soon" "Desktop Environment management will be available in a future update." 10 60 ;;
2) display_manager_menu ;;
3) break ;;
esac
done
}
display_manager_menu() {
while true; do
local choice
choice=$(_menu "Display Manager" \
"Select an option:" $TUI_ALTO $TUI_ANCHO 6 \
"1" "LightDM" \
"2" "Back")
[ -z "$choice" ] && break
clear
case "$choice" in
1) lightdm_config_menu ;;
2) break ;;
esac
done
}
lightdm_config_menu() {
local -a items=()
items+=("install_lightdm" "Install LightDM & GTK Greeter" "$(_state lightdm)")
items+=("enable_userlist" "Enable user list" "OFF")
local choices
choices=$(_checklist "LightDM Configuration" \
"Select options to apply:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
"${items[@]}")
if [ -z "$choices" ]; then
echo "No changes."
_pause
return
fi
local cleaned
cleaned=$(echo "$choices" | tr -d '"')
for item in $cleaned; do
case $item in
install_lightdm)
if ! is_installed lightdm; then
_run_cmd "LightDM" "sudo apt install -y lightdm" "Installing LightDM..."
else
echo -e "${GREEN}[LightDM] already installed, skipping...${NC}"
fi
if ! is_installed lightdm-gtk-greeter-settings; then
_run_cmd "LightDM Settings" "sudo apt install -y lightdm-gtk-greeter-settings" "Installing LightDM Settings..."
else
echo -e "${GREEN}[LightDM Settings] already installed, skipping...${NC}"
fi
;;
enable_userlist)
local conf="/etc/lightdm/lightdm.conf.d/50-debianito-userlist.conf"
sudo mkdir -p "$(dirname "$conf")"
if echo "[Seat:*]
greeter-hide-users=false" | sudo tee "$conf" > /dev/null; then
echo -e "${GREEN}User list enabled in LightDM.${NC}"
else
echo -e "${RED}Failed to write configuration.${NC}"
fi
;;
esac
done
_pause
}
+2 -3
View File
@@ -27,7 +27,7 @@ install_extras() {
while true; do
local cat_choice
cat_choice=$(whiptail --title "Extra Software" --menu \
cat_choice=$(_menu "Extra Software" \
"Select a category${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
"0" "Essential Pack" \
"1" "Customization System" \
@@ -42,8 +42,7 @@ install_extras() {
"10" "Office & Productivity" \
"11" "System Tools" \
"12" "Fetch / System Info" \
"13" "Back to main menu" \
3>&1 1>&2 2>&3)
"13" "Back to main menu")
[ -z "$cat_choice" ] && return
clear
+1 -8
View File
@@ -1,14 +1,6 @@
#!/usr/bin/env bash
# Shared helpers for extras categories
_inst() {
if is_installed "$1"; then echo " (installed)"; else echo ""; fi
}
_state() {
is_installed "$1" && echo "ON" || echo "OFF"
}
_install_clamav() {
if is_installed "clamav"; then
echo "ClamAV already installed."
@@ -21,6 +13,7 @@ _install_clamav() {
sudo systemctl stop clamav-freshclam 2>/dev/null || true
sudo freshclam || true
sudo systemctl start clamav-freshclam 2>/dev/null || true
_pause
fi
if _confirm "ClamAV" "Run quick scan on /bin to verify engine works?"; then
+23 -23
View File
@@ -4,10 +4,11 @@
_cat_design() {
local headless=false
_is_headless && headless=true
local -a items=()
if ! $headless; then
local audacity_state; audacity_state=$(_state "audacity")
local ardour_state; ardour_state=$(_state "ardour")
local blender_state; blender_state=$(_state "blender")
local ffmpeg_state; ffmpeg_state=$(_state "ffmpeg")
local gimp_state; gimp_state=$(_state "gimp")
local handbrake_state; handbrake_state=$(_state "handbrake")
local inkscape_state; inkscape_state=$(_state "inkscape")
@@ -17,35 +18,34 @@ _cat_design() {
local openshot_state; openshot_state=$(_state "openshot-qt")
local scribus_state; scribus_state=$(_state "scribus")
local shotcut_state; shotcut_state=$(_state "shotcut")
items+=(
"audacity" "Audio editor/recorder" "$audacity_state"
"ardour" "Digital audio workstation" "$ardour_state"
"blender" "3D modeling/animation" "$blender_state"
"gimp" "Image editor" "$gimp_state"
"handbrake" "Video transcoder" "$handbrake_state"
"inkscape" "Vector graphics editor" "$inkscape_state"
"kdenlive" "Video editor (KDE)" "$kdenlive_state"
"krita" "Digital painting" "$krita_state"
"obs-studio" "Screen recording" "$obs_state"
"openshot-qt" "Simple video editor" "$openshot_state"
"scribus" "Desktop publishing" "$scribus_state"
"shotcut" "Cross-platform video editor" "$shotcut_state"
)
fi
local ffmpeg_state; ffmpeg_state=$(_state "ffmpeg")
items+=("ffmpeg" "Multimedia framework (CLI)" "$ffmpeg_state")
local item_count=${#items[@]}
local lista_alto=$((item_count > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count))
local choices
choices=$(whiptail --title "Multimedia & Design" --checklist \
"Select multimedia and design tools${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
"audacity" "Audio editor/recorder$(_inst audacity)" "$audacity_state" \
"ardour" "Digital audio workstation$(_inst ardour)" "$ardour_state" \
"blender" "3D modeling/animation suite$(_inst blender)" "$blender_state" \
"ffmpeg" "Multimedia framework (CLI)$(_inst ffmpeg)" "$ffmpeg_state" \
"gimp" "Image editor (Photoshop alternative)$(_inst gimp)" "$gimp_state" \
"handbrake" "Video transcoder (DVD ripper)$(_inst handbrake)" "$handbrake_state" \
"inkscape" "Vector graphics editor$(_inst inkscape)" "$inkscape_state" \
"kdenlive" "Video editor (KDE)$(_inst kdenlive)" "$kdenlive_state" \
"krita" "Digital painting/illustration$(_inst krita)" "$krita_state" \
"obs-studio" "Screen recording/streaming$(_inst obs-studio)" "$obs_state" \
"openshot-qt" "Video editor (simple)$(_inst openshot-qt)" "$openshot_state" \
"scribus" "Desktop publishing (DTP)$(_inst scribus)" "$scribus_state" \
"shotcut" "Video editor (cross-platform)$(_inst shotcut)" "$shotcut_state" \
3>&1 1>&2 2>&3)
choices=$(_checklist "Multimedia & Design" "Select multimedia and design tools${SCROLL_HINT}:" \
$TUI_ALTO $TUI_ANCHO $lista_alto "${items[@]}")
clear
[ -z "$choices" ] && return
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
for pkg in $cleaned; do
if $headless; then
echo "Skipping $pkg (headless mode)"
continue
fi
if ! is_installed "$pkg"; then
_run_install "$pkg"
else
+23 -19
View File
@@ -4,6 +4,7 @@
_cat_dev() {
local headless=false
_is_headless && headless=true
local -a items=()
local apache_state; apache_state=$(_state "apache2")
local build_state; build_state=$(_state "build-essential")
local certbot_state; certbot_state=$(_state "certbot")
@@ -19,27 +20,30 @@ _cat_dev() {
local sqlite_state; sqlite_state=$(_state "sqlite3")
local jdk_desc; jdk_desc=$(_any_jdk_installed_desc)
local jdk_state; jdk_state=$(_any_jdk_state)
items+=(
"apache2" "Apache web server" "$apache_state"
"build-essential" "C/C++ build tools (gcc, make)" "$build_state"
"certbot" "Let's Encrypt TLS certificates" "$certbot_state"
"docker" "Docker + docker-compose" "$docker_state"
"mariadb-server" "MariaDB database server" "$mariadb_state"
"netcat-openbsd" "TCP/IP networking utility" "$netcat_state"
"nginx" "Nginx web server" "$nginx_state"
"openssh-server" "SSH server" "$ssh_state"
"openssl" "OpenSSL cryptography toolkit" "$openssl_state"
"postgresql" "PostgreSQL database server" "$pg_state"
"python3-pip" "Python 3 pip + venv + dev" "$pip_state"
"redis-server" "Redis key-value store" "$redis_state"
"sqlite3" "SQLite database engine" "$sqlite_state"
"jellyfin" "Jellyfin Media Server (Web GUI on port 8096)" OFF
"openjdk-dev-env" "Adoptium Temurin JDK (17, 21, 25 LTS)${jdk_desc}" "${jdk_state}"
)
local TUI_ANCHO_REFORZADO=$((TUI_ANCHO + 6))
local item_count=${#items[@]}
local lista_alto=$((item_count > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count))
local choices
choices=$(whiptail --title "Development & Servers" --checklist \
"Select development tools and servers${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO_REFORZADO $TUI_ALTO_LISTA \
"apache2" "Apache web server$(_inst apache2)" "$apache_state" \
"build-essential" "C/C++ build tools (gcc, make)$(_inst build-essential)" "$build_state" \
"certbot" "Let's Encrypt TLS certificates$(_inst certbot)" "$certbot_state" \
"docker" "Docker + docker-compose$(_inst docker.io)" "$docker_state" \
"mariadb-server" "MariaDB database server$(_inst mariadb-server)" "$mariadb_state" \
"netcat-openbsd" "TCP/IP networking utility$(_inst netcat-openbsd)" "$netcat_state" \
"nginx" "Nginx web server$(_inst nginx)" "$nginx_state" \
"openssh-server" "SSH server$(_inst openssh-server)" "$ssh_state" \
"openssl" "OpenSSL cryptography toolkit$(_inst openssl)" "$openssl_state" \
"postgresql" "PostgreSQL database server$(_inst postgresql)" "$pg_state" \
"python3-pip" "Python 3 pip + venv + dev$(_inst python3-pip)" "$pip_state" \
"redis-server" "Redis key-value store$(_inst redis-server)" "$redis_state" \
"sqlite3" "SQLite database engine$(_inst sqlite3)" "$sqlite_state" \
"jellyfin" "Jellyfin Media Server (Web GUI on port 8096)$(_inst jellyfin)" OFF \
"openjdk-dev-env" "Adoptium Temurin JDK (17, 21, 25 LTS)${jdk_desc}" "${jdk_state}" \
3>&1 1>&2 2>&3)
choices=$(_checklist "Development & Servers" "Select development tools and servers${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $lista_alto \
"${items[@]}" \
)
clear
[ -z "$choices" ] && return
+38 -28
View File
@@ -4,43 +4,57 @@
_cat_download() {
local headless=false
_is_headless && headless=true
local -a items1=()
local -a items2=()
local aria2_state; aria2_state=$(_state "aria2")
local filezilla_state; filezilla_state=$(_state "filezilla")
local ytdlp_state; ytdlp_state=$(_state "yt-dlp")
local ytdlp_gui_state; ytdlp_gui_state=$(_state "youtubedl-gui")
local deluge_state; deluge_state=$(_state "deluge")
local deluged_state; deluged_state=$(_state "deluged")
local mktorrent_state; mktorrent_state=$(_state "mktorrent")
local qbit_state; qbit_state=$(_state "qbittorrent")
local qbitnox_state; qbitnox_state=$(_state "qbittorrent-nox")
local tr_cli_state; tr_cli_state=$(_state "transmission-cli")
items1+=(
"aria2" "Multiprotocol downloader (CLI)" "$aria2_state"
"yt-dlp" "Video downloader CLI" "$ytdlp_state"
)
items2+=(
"deluged" "BitTorrent daemon/server" "$deluged_state"
"mktorrent" "Torrent metainfo creator (CLI)" "$mktorrent_state"
"qbittorrent-nox" "BitTorrent WebUI/CLI" "$qbitnox_state"
"transmission-cli" "BitTorrent client (CLI)" "$tr_cli_state"
)
if ! $headless; then
local filezilla_state; filezilla_state=$(_state "filezilla")
local ytdlp_gui_state; ytdlp_gui_state=$(_state "youtubedl-gui")
local deluge_state; deluge_state=$(_state "deluge")
local qbit_state; qbit_state=$(_state "qbittorrent")
local tr_gtk_state; tr_gtk_state=$(_state "transmission-gtk")
local tr_qt_state; tr_qt_state=$(_state "transmission-qt")
items1+=(
"filezilla" "FTP/SFTP client (GUI)" "$filezilla_state"
"youtubedl-gui" "GUI for yt-dlp" "$ytdlp_gui_state"
)
items2+=(
"deluge" "BitTorrent client (GTK)" "$deluge_state"
"qbittorrent" "BitTorrent client (Qt)" "$qbit_state"
"transmission-gtk" "BitTorrent client (GTK)" "$tr_gtk_state"
"transmission-qt" "BitTorrent client (Qt)" "$tr_qt_state"
)
fi
local TUI_ANCHO_REFORZADO=$((TUI_ANCHO + 6))
local item_count1=${#items1[@]}
local lista_alto1=$((item_count1 > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count1))
local choices1 choices2=""
choices1=$(whiptail --title "Downloaders" --checklist \
"Select download tools:" $TUI_ALTO $TUI_ANCHO_REFORZADO $TUI_ALTO_LISTA \
"aria2" "Multiprotocol downloader (CLI)$(_inst aria2)" "$aria2_state" \
"filezilla" "FTP/SFTP client (GUI)$(_inst filezilla)" "$filezilla_state" \
"yt-dlp" "Video downloader CLI$(_inst yt-dlp)" "$ytdlp_state" \
"youtubedl-gui" "GUI for yt-dlp$(_inst youtubedl-gui)" "$ytdlp_gui_state" \
3>&1 1>&2 2>&3)
choices1=$(_checklist "Downloaders" "Select download tools:" $TUI_ALTO $TUI_ANCHO $lista_alto1 \
"${items1[@]}" \
)
clear
choices2=$(whiptail --title "Torrent Clients" --checklist \
"Select torrent clients:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
"deluge" "BitTorrent client (GTK)$(_inst deluge)" "$deluge_state" \
"deluged" "BitTorrent daemon/server$(_inst deluged)" "$deluged_state" \
"mktorrent" "Torrent metainfo creator (CLI)$(_inst mktorrent)" "$mktorrent_state" \
"qbittorrent" "BitTorrent client (Qt)$(_inst qbittorrent)" "$qbit_state" \
"qbittorrent-nox" "BitTorrent WebUI/CLI$(_inst qbittorrent-nox)" "$qbitnox_state" \
"transmission-cli" "BitTorrent client (CLI)$(_inst transmission-cli)" "$tr_cli_state" \
"transmission-gtk" "BitTorrent client (GTK)$(_inst transmission-gtk)" "$tr_gtk_state" \
"transmission-qt" "BitTorrent client (Qt)$(_inst transmission-qt)" "$tr_qt_state" \
3>&1 1>&2 2>&3)
local item_count2=${#items2[@]}
local lista_alto2=$((item_count2 > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count2))
choices2=$(_checklist "Torrent Clients" "Select torrent clients:" $TUI_ALTO $TUI_ANCHO $lista_alto2 \
"${items2[@]}" \
)
clear
local cleaned
@@ -60,10 +74,6 @@ _cat_download() {
install_backports_or_stable qbittorrent-nox
;;
*)
if $headless; then
echo "Skipping $pkg (headless mode)"
continue
fi
if ! is_installed "$pkg"; then
_run_install "$pkg"
else
+3 -2
View File
@@ -10,12 +10,13 @@ _quick_install() {
fi
_msg "Essential Pack" \
"Install basic programs:\n\n - Compression (zip, unrar, 7z)\n - System tools (htop, inxi, ${fetch_pkg})\n - VLC media player\n - Microsoft fonts" 13 60
"Install basic programs:\n\n - Compression (zip, unrar, 7z)\n - System tools (htop, inxi, ${fetch_pkg}, $(_is_headless || echo "VLC"))\n - Microsoft fonts" 13 60
local quick_pkgs=(
zip unzip rar unrar p7zip-full p7zip-rar
"$fetch_pkg" htop vlc inxi ttf-mscorefonts-installer
"$fetch_pkg" htop inxi ttf-mscorefonts-installer
)
_is_headless || quick_pkgs+=(vlc)
_run_install_batch "${quick_pkgs[@]}"
echo -e "${GREEN}Essential Pack installed.${NC}"
}
+11 -11
View File
@@ -18,29 +18,29 @@ _cat_fetch() {
hyfetch_state=$(_state "hyfetch")
fi
local items=()
local -a items=()
if [ "$fetch_pkg" = "fastfetch" ]; then
items+=("fastfetch" "System info fetcher$(_inst fastfetch)" "$fetch_state")
items+=("fastfetch" "System info fetcher" "$fetch_state")
if [ "$DEBIAN_CODENAME" = "trixie" ]; then
items+=("hyfetch" "Neofetch with pride flags$(_inst hyfetch)" "$hyfetch_state")
items+=("hyfetch" "Neofetch with pride flags" "$hyfetch_state")
fi
fi
items+=("linuxlogo" "Linux logo + system info$(_inst linuxlogo)" "$linuxlogo_state")
items+=("linuxlogo" "Linux logo + system info" "$linuxlogo_state")
if [ "$fetch_pkg" = "neofetch" ]; then
items+=("neofetch" "System info fetcher$(_inst neofetch)" "$fetch_state")
items+=("neofetch" "System info fetcher" "$fetch_state")
if [ "$DEBIAN_CODENAME" = "trixie" ]; then
items+=("hyfetch" "Neofetch with pride flags$(_inst hyfetch)" "$hyfetch_state")
items+=("hyfetch" "Neofetch with pride flags" "$hyfetch_state")
fi
fi
items+=("screenfetch" "System info (BSD/Linux)$(_inst screenfetch)" "$screenfetch_state")
items+=("screenfetch" "System info (BSD/Linux)" "$screenfetch_state")
local TUI_ANCHO_REFORZADO=$((TUI_ANCHO + 6))
local item_count=${#items[@]}
local lista_alto=$((item_count > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count))
local choices
choices=$(whiptail --title "Fetch Tools" --checklist \
"Select system info tools:" $TUI_ALTO $TUI_ANCHO_REFORZADO $TUI_ALTO_LISTA \
choices=$(_checklist "Fetch Tools" "Select system info tools:" $TUI_ALTO $TUI_ANCHO $lista_alto \
"${items[@]}" \
3>&1 1>&2 2>&3)
)
clear
[ -z "$choices" ] && return
+86 -34
View File
@@ -1,6 +1,7 @@
#!/usr/bin/env bash
# internet.sh — Browsers, email, VPN
# extrepo-powered: mozilla, floorp, palemoon, librewolf, tailscale, mullvad, protonvpn
# firefox-esr from Debian repos (with locale auto-detect)
# ── Helpers extrepo ──
_ensure_extrepo() {
@@ -116,65 +117,85 @@ install_protonvpn() {
_cat_internet() {
local headless=false
_is_headless && headless=true
local -a items=()
if ! $headless; then
local chromium_state; chromium_state=$(_state "chromium")
local dillo_state; dillo_state=$(_state "dillo")
local elinks_state; elinks_state=$(_state "elinks")
local epiphany_state; epiphany_state=$(_state "epiphany-browser")
local falkon_state; falkon_state=$(_state "falkon")
local firefox_state="OFF"
if command -v firefox &>/dev/null && ! command -v firefox-esr &>/dev/null; then
if command -v firefox &>/dev/null && ! is_installed "firefox-esr"; then
firefox_state="ON"
fi
local firefox_esr_state
firefox_esr_state=$(_state "firefox-esr")
local floorp_state; floorp_state=$(_state "floorp")
local konqueror_state; konqueror_state=$(_state "konqueror")
local librewolf_state; librewolf_state=$(_state "librewolf")
local palemoon_state; palemoon_state=$(_state "palemoon")
local privacybrowser_state; privacybrowser_state=$(_state "privacybrowser")
local qutebrowser_state; qutebrowser_state=$(_state "qutebrowser")
local riseupvpn_state; riseupvpn_state=$(_state "riseup-vpn")
local thunderbird_state; thunderbird_state=$(_state "thunderbird")
local torbrowser_state; torbrowser_state=$(_state "torbrowser-launcher")
local mullvadbrowser_state; mullvadbrowser_state=$(_state "mullvad-browser")
local protonvpn_state; protonvpn_state=$(_state "protonvpn")
items+=(
"chromium" "Chromium web browser" "$chromium_state"
"dillo" "Lightweight graphical browser" "$dillo_state"
"epiphany-browser" "GNOME web browser" "$epiphany_state"
"falkon" "KDE web browser (QtWebEngine)" "$falkon_state"
"firefox" "Firefox from Mozilla (replaces ESR)" "$firefox_state"
"firefox-esr" "Firefox ESR (official Debian + locale auto)" "$firefox_esr_state"
"floorp" "Firefox-based browser (extrepo)" "$floorp_state"
"konqueror" "KDE file manager / web browser" "$konqueror_state"
"librewolf" "Privacy-focused Firefox fork (extrepo)" "$librewolf_state"
"palemoon" "Classic Firefox-derived browser (extrepo)" "$palemoon_state"
"privacybrowser" "Privacy-focused web browser" "$privacybrowser_state"
"qutebrowser" "Keyboard-driven browser (Qt)" "$qutebrowser_state"
"thunderbird" "Email client" "$thunderbird_state"
"torbrowser-launcher" "Tor Browser launcher" "$torbrowser_state"
"mullvad-browser" "Mullvad privacy browser" "$mullvadbrowser_state"
"protonvpn" "ProtonVPN client" "$protonvpn_state"
)
fi
local elinks_state; elinks_state=$(_state "elinks")
local riseupvpn_state; riseupvpn_state=$(_state "riseup-vpn")
local w3m_state; w3m_state=$(_state "w3m")
local tailscale_state; tailscale_state=$(_state "tailscale")
local mullvad_state; mullvad_state=$(_state "mullvad-vpn")
local mullvadbrowser_state; mullvadbrowser_state=$(_state "mullvad-browser")
local protonvpn_state; protonvpn_state=$(_state "protonvpn")
items+=(
"elinks" "Text-mode web browser" "$elinks_state"
"riseup-vpn" "Riseup VPN client" "$riseupvpn_state"
"w3m" "Text-mode browser + deps (w3m-img)" "$w3m_state"
"tailscale" "Zero-config VPN & mesh networking" "$tailscale_state"
"mullvad-vpn" "Mullvad VPN client (WireGuard)" "$mullvad_state"
)
local item_count=${#items[@]}
local lista_alto=$((item_count > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count))
local choices
choices=$(whiptail --title "Internet" --checklist \
"Select browsers, email, and VPN tools${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
"chromium" "Chromium web browser$(_inst chromium)" "$chromium_state" \
"dillo" "Lightweight graphical browser$(_inst dillo)" "$dillo_state" \
"elinks" "Text-mode web browser$(_inst elinks)" "$elinks_state" \
"epiphany-browser" "GNOME web browser$(_inst epiphany-browser)" "$epiphany_state" \
"falkon" "KDE web browser (QtWebEngine)$(_inst falkon)" "$falkon_state" \
"firefox" "Firefox from Mozilla (replaces ESR)" "$firefox_state" \
"floorp" "Firefox-based browser (extrepo)$(_inst floorp)" "$floorp_state" \
"konqueror" "KDE file manager / web browser$(_inst konqueror)" "$konqueror_state" \
"librewolf" "Privacy-focused Firefox fork (extrepo)$(_inst librewolf)" "$librewolf_state" \
"palemoon" "Classic Firefox-derived browser (extrepo)" "$palemoon_state" \
"privacybrowser" "Privacy-focused web browser$(_inst privacybrowser)" "$privacybrowser_state" \
"qutebrowser" "Keyboard-driven browser (Qt)$(_inst qutebrowser)" "$qutebrowser_state" \
"riseup-vpn" "Riseup VPN client$(_inst riseup-vpn)" "$riseupvpn_state" \
"thunderbird" "Email client$(_inst thunderbird)" "$thunderbird_state" \
"torbrowser-launcher" "Tor Browser launcher$(_inst torbrowser-launcher)" "$torbrowser_state" \
"w3m" "Text-mode browser + deps (w3m-img)$(_inst w3m)" "$w3m_state" \
"tailscale" "Zero-config VPN & mesh networking$(_inst tailscale)" "$tailscale_state" \
"mullvad-vpn" "Mullvad VPN client (WireGuard)$(_inst mullvad-vpn)" "$mullvad_state" \
"mullvad-browser" "Mullvad privacy browser$(_inst mullvad-browser)" "$mullvadbrowser_state" \
"protonvpn" "ProtonVPN client$(_inst protonvpn)" "$protonvpn_state" \
3>&1 1>&2 2>&3)
choices=$(_checklist "Internet" "Select browsers, email, and VPN tools${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $lista_alto \
"${items[@]}" \
)
clear
[ -z "$choices" ] && return
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
fi
for pkg in $cleaned; do
case $pkg in
firefox)
install_firefox_mozilla
;;
firefox-esr)
install_firefox_esr
;;
floorp)
_enable_floorp_repo
_run_install floorp
@@ -222,10 +243,6 @@ _cat_internet() {
fi
;;
*)
if $headless; then
echo "Skipping $pkg (headless mode)"
continue
fi
if ! is_installed "$pkg"; then
_run_install "$pkg"
else
@@ -239,7 +256,12 @@ _cat_internet() {
}
install_firefox_mozilla() {
if command -v firefox &>/dev/null && ! command -v firefox-esr &>/dev/null; then
if [ "$DEBIAN_VERSION" -lt 12 ] 2>/dev/null; then
_msg "Firefox" "Mozilla Firefox is only available on\nDebian 12 (Bookworm) and 13 (Trixie).\n\nSkipping installation." 10 60
return 1
fi
if command -v firefox &>/dev/null && ! is_installed "firefox-esr"; then
echo "Firefox (Mozilla) is already installed."
return
fi
@@ -255,6 +277,36 @@ install_firefox_mozilla() {
fi
_enable_mozilla_repo
_run_install firefox
_run_cmd "Firefox" "sudo apt install -y firefox" "Installing Firefox (Mozilla)..."
echo -e "${GREEN}Firefox (Mozilla) installed.${NC}"
}
install_firefox_esr() {
if is_installed "firefox-esr"; then
echo "Firefox ESR is already installed."
return
fi
if command -v firefox &>/dev/null; then
if _confirm "Firefox" "Mozilla Firefox is installed.\nRemove it before installing Firefox ESR?"; then
echo "Removing Mozilla Firefox..."
sudo apt remove -y firefox
else
echo "Keeping Mozilla Firefox."
return
fi
fi
_run_cmd "Firefox ESR" "sudo apt install -y firefox-esr" "Installing Firefox ESR..."
local lang_pkg
lang_pkg=$(_detect_lang_pkg "firefox-esr-l10n")
if [ -n "$lang_pkg" ]; then
_run_cmd "Firefox ESR Locale" "sudo apt install -y ${lang_pkg}" \
"Installing locale: ${lang_pkg}..."
else
echo "No matching locale package found for your language."
fi
echo -e "${GREEN}Firefox ESR installed.${NC}"
}
+13 -11
View File
@@ -14,27 +14,29 @@ _enable_temurin_repo() {
}
install_minecraft_java() {
local ver
ver=$(whiptail --title "Java Runtimes for Minecraft" --menu \
"Select Java version:" 12 65 3 \
"8" "Java 8 — Classic mods & Minecraft <= 1.16.5" \
"17" "Java 17 — Minecraft 1.17 to 1.20.4" \
"21" "Java 21 — Modern Minecraft >= 1.20.5 & 1.21+" \
3>&1 1>&2 2>&3)
[ -z "$ver" ] && { echo "No Java version selected."; return; }
local choices
choices=$(_checklist "Java Runtimes for Minecraft" \
"Select Java version(s) to install:" 14 65 3 \
"8" "Java 8 — Classic mods & Minecraft <= 1.16.5" OFF \
"17" "Java 17 — Minecraft 1.17 to 1.20.4" ON \
"21" "Java 21 — Modern Minecraft >= 1.20.5 & 1.21+" OFF)
[ -z "$choices" ] && { echo "No Java version selected."; return; }
_enable_temurin_repo
local cleaned
cleaned=$(echo "$choices" | tr -d '"')
for ver in $cleaned; do
_run_cmd "Java" "sudo apt install -y temurin-${ver}-jre" \
"Installing Temurin JRE ${ver}..."
done
}
_install_dev_java() {
local ver
ver=$(whiptail --title "Java Development Kits (JDK)" --menu \
ver=$(_menu "Java Development Kits (JDK)" \
"Select JDK version:" 12 60 3 \
"17" "Java 17 LTS Development Kit" \
"21" "Java 21 LTS Development Kit" \
"25" "Java 25 LTS Development Kit" \
3>&1 1>&2 2>&3)
"25" "Java 25 LTS Development Kit")
[ -z "$ver" ] && { echo "No JDK version selected."; return; }
_enable_temurin_repo
_run_install "temurin-${ver}-jdk"
+17 -15
View File
@@ -33,16 +33,8 @@ install_libreoffice_bpo() {
return
fi
local sys_lang
sys_lang=$(echo "${LANG:-en}" | cut -c1-2 | tr '[:upper:]' '[:lower:]')
local lang_pkg=""
if [ "$sys_lang" != "en" ]; then
local candidate="libreoffice-l10n-${sys_lang}"
if apt-cache show "$candidate" &>/dev/null 2>&1; then
lang_pkg="$candidate"
fi
fi
local lang_pkg
lang_pkg=$(_detect_lang_pkg "libreoffice-l10n")
local ver
ver=$(apt-cache policy libreoffice 2>/dev/null | awk 'NR==3 {print $2; exit}')
@@ -68,12 +60,22 @@ install_libreoffice_bpo() {
}
_cat_office() {
local headless=false
_is_headless && headless=true
local -a items=()
if ! $headless; then
items+=(
"onlyoffice" "OnlyOffice Desktop Editors (extrepo)" OFF
"libreoffice" "LibreOffice (backports on Bookworm/Trixie)" OFF
)
fi
local item_count=${#items[@]}
local lista_alto=$((item_count > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count))
local choices
choices=$(whiptail --title "Office & Productivity" --checklist \
"Select office applications${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
"onlyoffice" "OnlyOffice Desktop Editors (extrepo)" OFF \
"libreoffice" "LibreOffice (backports on Bookworm/Trixie)" OFF \
3>&1 1>&2 2>&3)
choices=$(_checklist "Office & Productivity" "Select office applications${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $lista_alto \
"${items[@]}" \
)
[ -z "$choices" ] && return
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
+12 -10
View File
@@ -4,16 +4,22 @@
_cat_players() {
local headless=false
_is_headless && headless=true
local -a items=()
if ! $headless; then
local mpv_state; mpv_state=$(_state "mpv")
local vlc_state; vlc_state=$(_state "vlc")
items+=(
"mpv" "Lightweight media player" "$mpv_state"
"vlc" "VLC media player" "$vlc_state"
)
fi
local TUI_ANCHO_REFORZADO=$((TUI_ANCHO + 6))
local item_count=${#items[@]}
local lista_alto=$((item_count > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count))
local choices
choices=$(whiptail --title "Media Players" --checklist \
"Select media players:" $TUI_ALTO $TUI_ANCHO_REFORZADO $TUI_ALTO_LISTA \
"mpv" "Lightweight media player$(_inst mpv)" "$mpv_state" \
"vlc" "VLC media player$(_inst vlc)" "$vlc_state" \
3>&1 1>&2 2>&3)
choices=$(_checklist "Media Players" "Select media players:" $TUI_ALTO $TUI_ANCHO $lista_alto \
"${items[@]}" \
)
clear
[ -z "$choices" ] && return
@@ -21,10 +27,6 @@ _cat_players() {
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
for pkg in $cleaned; do
if $headless; then
echo "Skipping $pkg (headless mode)"
continue
fi
if ! is_installed "$pkg"; then
_run_install "$pkg"
else
+25 -21
View File
@@ -4,12 +4,21 @@
_cat_programming() {
local headless=false
_is_headless && headless=true
local -a items=()
local vim_state; vim_state=$(_state "vim")
local vimgtk_state; vimgtk_state=$(_state "vim-gtk3")
local neovim_state; neovim_state=$(_state "neovim")
local hx_state; hx_state=$(_state "hx")
local nano_state; nano_state=$(_state "nano")
local emacs_state; emacs_state=$(_state "emacs")
items+=(
"vim" "Classic terminal editor" "$vim_state"
"neovim" "Modern vim fork" "$neovim_state"
"hx" "Helix modal editor (Rust)" "$hx_state"
"nano" "Simple terminal editor" "$nano_state"
"emacs" "Extensible editor / IDE" "$emacs_state"
)
if ! $headless; then
local vimgtk_state; vimgtk_state=$(_state "vim-gtk3")
local kate_state; kate_state=$(_state "kate")
local mousepad_state; mousepad_state=$(_state "mousepad")
local gedit_state; gedit_state=$(_state "gedit")
@@ -19,24 +28,23 @@ _cat_programming() {
if command -v codium &>/dev/null; then
codium_state="ON"
fi
items+=(
"vim-gtk3" "Vim with GTK3 GUI" "$vimgtk_state"
"kate" "KDE advanced text editor" "$kate_state"
"mousepad" "Xfce text editor" "$mousepad_state"
"gedit" "GNOME text editor" "$gedit_state"
"geany" "Lightweight IDE" "$geany_state"
"gnome-text-editor" "GNOME modern text editor" "$gte_state"
"vscodium" "VS Code open-source (extrepo)" "$codium_state"
)
fi
local TUI_ANCHO_REFORZADO=$((TUI_ANCHO + 6))
local item_count=${#items[@]}
local lista_alto=$((item_count > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count))
local choices
choices=$(whiptail --title "Programming Applications" --checklist \
"Select editors and IDEs${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO_REFORZADO $TUI_ALTO_LISTA \
"vim" "Classic terminal editor$(_inst vim)" "$vim_state" \
"vim-gtk3" "Vim with GTK3 GUI$(_inst vim-gtk3)" "$vimgtk_state" \
"neovim" "Modern vim fork$(_inst neovim)" "$neovim_state" \
"hx" "Helix modal editor (Rust)$(_inst hx)" "$hx_state" \
"nano" "Simple terminal editor$(_inst nano)" "$nano_state" \
"emacs" "Extensible editor / IDE$(_inst emacs)" "$emacs_state" \
"kate" "KDE advanced text editor$(_inst kate)" "$kate_state" \
"mousepad" "Xfce text editor$(_inst mousepad)" "$mousepad_state" \
"gedit" "GNOME text editor$(_inst gedit)" "$gedit_state" \
"geany" "Lightweight IDE$(_inst geany)" "$geany_state" \
"gnome-text-editor" "GNOME modern text editor$(_inst gnome-text-editor)" "$gte_state" \
"vscodium" "VS Code open-source (extrepo)$(_inst codium)" "$codium_state" \
3>&1 1>&2 2>&3)
choices=$(_checklist "Programming Applications" "Select editors and IDEs${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $lista_alto \
"${items[@]}" \
)
clear
[ -z "$choices" ] && return
@@ -49,10 +57,6 @@ _cat_programming() {
install_vscodium
;;
*)
if $headless; then
echo "Skipping $pkg (headless mode)"
continue
fi
if ! is_installed "$pkg"; then
_run_install "$pkg"
else
+19 -11
View File
@@ -4,24 +4,32 @@
_cat_security() {
local headless=false
_is_headless && headless=true
local -a items=()
if ! $headless; then
local wireshark_state; wireshark_state=$(_state "wireshark")
local tcpdump_state; tcpdump_state=$(_state "tcpdump")
local zenmap_state; zenmap_state=$(_state "zenmap")
items+=(
"wireshark" "Network protocol analyzer (GUI)" "$wireshark_state"
"zenmap" "Network scanner GUI (Nmap frontend)" "$zenmap_state"
)
fi
local tcpdump_state; tcpdump_state=$(_state "tcpdump")
local fail2ban_state; fail2ban_state=$(_state "fail2ban")
local ufw_state; ufw_state=$(_state "ufw")
local clamav_state; clamav_state=$(_state "clamav")
items+=(
"tcpdump" "Command-line packet analyzer" "$tcpdump_state"
"fail2ban" "Brute-force protection daemon" "$fail2ban_state"
"ufw" "Uncomplicated firewall" "$ufw_state"
"clamav" "Antivirus engine (ClamAV)" "$clamav_state"
)
local TUI_ANCHO_REFORZADO=$((TUI_ANCHO + 6))
local item_count=${#items[@]}
local lista_alto=$((item_count > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count))
local choices
choices=$(whiptail --title "Security & Networking" --checklist \
"Select security and networking tools${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO_REFORZADO $TUI_ALTO_LISTA \
"wireshark" "Network protocol analyzer (GUI)$(_inst wireshark)" "$wireshark_state" \
"tcpdump" "Command-line packet analyzer$(_inst tcpdump)" "$tcpdump_state" \
"zenmap" "Network scanner GUI (Nmap frontend)$(_inst zenmap)" "$zenmap_state" \
"fail2ban" "Brute-force protection daemon$(_inst fail2ban)" "$fail2ban_state" \
"ufw" "Uncomplicated firewall$(_inst ufw)" "$ufw_state" \
"clamav" "Antivirus engine (ClamAV)$(_inst clamav)" "$clamav_state" \
3>&1 1>&2 2>&3)
choices=$(_checklist "Security & Networking" "Select security and networking tools${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $lista_alto \
"${items[@]}" \
)
clear
[ -z "$choices" ] && return
+10 -5
View File
@@ -1,14 +1,19 @@
# software_centers.sh — Standalone Software Center installer
_cat_software_centers() {
local headless=false
_is_headless && headless=true
if $headless; then
echo "Software centers require a GUI — skipping."
return
fi
local de_type
de_type=$(_detect_desktop_type)
local sc_choice
sc_choice=$(whiptail --title "Software Centers" --menu \
"Choose a software store to install:" 12 65 2 \
"gnome-software" "Software Center for GNOME$(_inst gnome-software)" \
"plasma-discover" "Software manager for Plasma$(_inst plasma-discover)" \
3>&1 1>&2 2>&3)
sc_choice=$(_menu "Software Centers" "Choose a software store to install:" 12 65 2 \
"gnome-software" "Software Center for GNOME" \
"plasma-discover" "Software manager for Plasma" \
)
[ -z "$sc_choice" ] && return
if { [ "$de_type" = "qt" ] && [ "$sc_choice" = "gnome-software" ]; } || \
+67 -60
View File
@@ -19,7 +19,7 @@ _detect_desktop_type() {
_cat_general() {
local headless=false
_is_headless && headless=true
local alacritty_state; alacritty_state=$(_state "alacritty")
local -a items=()
local btop_state; btop_state=$(_state "btop")
local compress_state
if is_installed "zip" && is_installed "unzip" && is_installed "p7zip-full"; then
@@ -27,8 +27,6 @@ _cat_general() {
else
compress_state="OFF"
fi
local conky_state; conky_state=$(_state "conky")
local corectrl_state; corectrl_state=$(_state "corectrl")
local cpufetch_state; cpufetch_state=$(_state "cpufetch")
local cpu_x_state; cpu_x_state=$(_state "cpu-x")
local curl_wget_state
@@ -37,62 +35,72 @@ _cat_general() {
else
curl_wget_state="OFF"
fi
local dcgtk_state; dcgtk_state=$(_state "doublecmd-gtk")
local dcqt_state; dcqt_state=$(_state "doublecmd-qt")
local extrepo_state; extrepo_state=$(_state "extrepo")
local flatpak_state; flatpak_state=$(_state "flatpak")
local fwupd_state; fwupd_state=$(_state "fwupd")
local disks_state; disks_state=$(_state "gnome-disk-utility")
local gparted_state; gparted_state=$(_state "gparted")
local hardinfo_state; hardinfo_state=$(_state "hardinfo")
local htop_state; htop_state=$(_state "htop")
local inxi_state; inxi_state=$(_state "inxi")
local kitty_state; kitty_state=$(_state "kitty")
local kvm_state; kvm_state=$(_state "virt-manager")
local lshw_state; lshw_state=$(_state "lshw")
local mc_state; mc_state=$(_state "mc")
local nala_state; nala_state=$(_state "nala")
local ncdu_state; ncdu_state=$(_state "ncdu")
local psensor_state; psensor_state=$(_state "psensor")
local timeshift_state; timeshift_state=$(_state "timeshift")
local tmux_state; tmux_state=$(_state "tmux")
local wine_state; wine_state=$(_state "wine")
local nvme_state; nvme_state=$(_state "nvme-cli")
items+=(
"btop" "Resource monitor (fancy top)" "$btop_state"
"compress" "Compression tools (zip, unrar, 7z)" "$compress_state"
"cpufetch" "CPU info fetcher" "$cpufetch_state"
"cpu-x" "CPU-X (alternative to CPU-Z)" "$cpu_x_state"
"curl-wget" "HTTP transfer tools (curl, wget)" "$curl_wget_state"
"extrepo" "External repository manager" "$extrepo_state"
"flatpak" "Flatpak sandbox + Flathub" "$flatpak_state"
"fwupd" "Firmware update daemon" "$fwupd_state"
"htop" "Interactive process viewer" "$htop_state"
"inxi" "System information tool" "$inxi_state"
"kvm" "QEMU/KVM virtualization" "$kvm_state"
"lshw" "List hardware details" "$lshw_state"
"mc" "Midnight Commander (file manager)" "$mc_state"
"nala" "APT frontend (parallel downloads)" "$nala_state"
"ncdu" "Disk usage analyzer (ncurses)" "$ncdu_state"
"nvme-cli" "NVMe SSD health monitoring" "$nvme_state"
"tmux" "Terminal multiplexer" "$tmux_state"
"wine" "Windows compatibility layer" "$wine_state"
)
if ! $headless; then
local alacritty_state; alacritty_state=$(_state "alacritty")
local conky_state; conky_state=$(_state "conky")
local corectrl_state; corectrl_state=$(_state "corectrl")
local dcgtk_state; dcgtk_state=$(_state "doublecmd-gtk")
local dcqt_state; dcqt_state=$(_state "doublecmd-qt")
local disks_state; disks_state=$(_state "gnome-disk-utility")
local gparted_state; gparted_state=$(_state "gparted")
local hardinfo_state; hardinfo_state=$(_state "hardinfo")
local kitty_state; kitty_state=$(_state "kitty")
local psensor_state; psensor_state=$(_state "psensor")
local timeshift_state; timeshift_state=$(_state "timeshift")
items+=(
"alacritty" "GPU-accelerated terminal" "$alacritty_state"
"conky" "System monitor for desktop" "$conky_state"
"corectrl" "AMD GPU control (CoreCtrl)" "$corectrl_state"
"doublecmd-gtk" "Dual-panel file manager (GTK)" "$dcgtk_state"
"doublecmd-qt" "Dual-panel file manager (Qt)" "$dcqt_state"
"gnome-disk-utility" "Disk management GUI" "$disks_state"
"gparted" "GNOME partition editor" "$gparted_state"
"hardinfo" "Graphical system profiler" "$hardinfo_state"
"kitty" "GPU-based terminal emulator" "$kitty_state"
"psensor" "Hardware temperature monitor" "$psensor_state"
"timeshift" "System restore snapshots" "$timeshift_state"
)
fi
local TUI_ANCHO_REFORZADO=$((TUI_ANCHO + 6))
local item_count=${#items[@]}
local lista_alto=$((item_count > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count))
local choices
choices=$(whiptail --title "System Tools" --checklist \
"Select system utilities to install${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO_REFORZADO $TUI_ALTO_LISTA \
"alacritty" "GPU-accelerated terminal$(_inst alacritty)" "$alacritty_state" \
"btop" "Resource monitor (fancy top)$(_inst btop)" "$btop_state" \
"compress" "Compression tools (zip, unrar, 7z)$(_inst zip)" "$compress_state" \
"conky" "System monitor for desktop$(_inst conky)" "$conky_state" \
"corectrl" "AMD GPU control (CoreCtrl)$(_inst corectrl)" "$corectrl_state" \
"cpufetch" "CPU info fetcher$(_inst cpufetch)" "$cpufetch_state" \
"cpu-x" "CPU-X (alternative to CPU-Z)$(_inst cpu-x)" "$cpu_x_state" \
"curl-wget" "HTTP transfer tools (curl, wget)$(_inst curl)" "$curl_wget_state" \
"doublecmd-gtk" "Dual-panel file manager (GTK)$(_inst doublecmd-gtk)" "$dcgtk_state" \
"doublecmd-qt" "Dual-panel file manager (Qt)$(_inst doublecmd-qt)" "$dcqt_state" \
"extrepo" "External repository manager$(_inst extrepo)" "$extrepo_state" \
"flatpak" "Flatpak sandbox + Flathub$(_inst flatpak)" "$flatpak_state" \
"fwupd" "Firmware update daemon$(_inst fwupd)" "$fwupd_state" \
"gnome-disk-utility" "Disk management GUI$(_inst gnome-disk-utility)" "$disks_state" \
"gparted" "GNOME partition editor$(_inst gparted)" "$gparted_state" \
"hardinfo" "Graphical system profiler$(_inst hardinfo)" "$hardinfo_state" \
"htop" "Interactive process viewer$(_inst htop)" "$htop_state" \
"inxi" "System information tool$(_inst inxi)" "$inxi_state" \
"kitty" "GPU-based terminal emulator$(_inst kitty)" "$kitty_state" \
"kvm" "QEMU/KVM virtualization$(_inst virt-manager)" "$kvm_state" \
"lshw" "List hardware details$(_inst lshw)" "$lshw_state" \
"mc" "Midnight Commander (file manager)$(_inst mc)" "$mc_state" \
"nvme-cli" "NVMe SSD health monitoring$(_inst nvme-cli)" "$nvme_state" \
"nala" "APT frontend (parallel downloads)$(_inst nala)" "$nala_state" \
"ncdu" "Disk usage analyzer (ncurses)$(_inst ncdu)" "$ncdu_state" \
"psensor" "Hardware temperature monitor$(_inst psensor)" "$psensor_state" \
"timeshift" "System restore snapshots$(_inst timeshift)" "$timeshift_state" \
"tmux" "Terminal multiplexer$(_inst tmux)" "$tmux_state" \
"wine" "Windows compatibility layer$(_inst wine)" "$wine_state" \
3>&1 1>&2 2>&3)
choices=$(_checklist "System Tools" "Select system utilities to install${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $lista_alto \
"${items[@]}" \
)
clear
[ -z "$choices" ] && return
@@ -180,12 +188,15 @@ _cat_general() {
_run_cmd "fwupd" "sudo fwupdmgr update -y" "Installing firmware updates..."
else
echo "Skipping firmware update."
_pause
fi
else
echo "No firmware updates available."
_pause
fi
fi
echo -e "${GREEN}fwupd setup complete.${NC}"
_pause
;;
kvm)
if ! is_installed "virt-manager"; then
@@ -198,17 +209,17 @@ _cat_general() {
fi
;;
wine)
if ! is_installed "wine"; then
echo "Checking for i386 architecture..."
if ! dpkg --print-foreign-architectures 2>/dev/null | grep -q i386; then
echo "Enabling i386 architecture for Wine..."
sudo dpkg --add-architecture i386
_run_cmd "APT Update" "sudo apt update" "Updating package lists..."
fi
_run_cmd "Wine" "sudo apt install -y wine wine32 wine64 libwine libwine:i386 fonts-wine" "Installing Wine..."
echo -e "${GREEN}Wine installed. Run 'winecfg' to configure.${NC}"
if ! is_installed "wine64"; then
_run_cmd "Wine" "sudo apt install -y --no-install-recommends wine64 fonts-wine" "Installing Wine (64-bit only)..."
local wine_ver
wine_ver=$(wine --version 2>/dev/null)
if [ -n "$wine_ver" ]; then
echo -e "${GREEN}Wine (64-bit) installed: ${wine_ver}${NC}"
else
echo "Wine already installed."
echo -e "${YELLOW}Wine installed but version check failed.${NC}"
fi
else
echo "Wine64 already installed."
fi
;;
nvme-cli)
@@ -250,15 +261,10 @@ _cat_general() {
echo -e " ${GREEN}Percentage Used:${NC} ${pu:-N/A}"
echo ""
done
echo "Press [ENTER] to continue..."
read -r
_pause
fi
;;
*)
if $headless; then
echo "Skipping $pkg (headless mode)"
continue
fi
if ! is_installed "$pkg"; then
_run_install "$pkg"
else
@@ -269,5 +275,6 @@ _cat_general() {
done
echo -e "${GREEN}System tools installed.${NC}"
_pause
}
+18 -9
View File
@@ -2,23 +2,32 @@
# cursors.sh — Cursor themes
_cat_cursors() {
local headless=false
_is_headless && headless=true
local -a items=()
if ! $headless; then
local bibata_state; bibata_state=$(_state "bibata-cursor-theme")
local breeze_state; breeze_state=$(_state "breeze-cursor-theme")
local chameleon_state; chameleon_state=$(_state "chameleon-cursor-theme")
local dmz_state; dmz_state=$(_state "dmz-cursor-theme")
local xcursor_state; xcursor_state=$(_state "xcursor-themes")
local oxygen_state; oxygen_state=$(_state "oxygencursors")
items+=(
"bibata-cursor-theme" "Bibata cursors" "$bibata_state"
"breeze-cursor-theme" "Breeze cursors (KDE)" "$breeze_state"
"chameleon-cursor-theme" "Chameleon cursors" "$chameleon_state"
"dmz-cursor-theme" "DMZ cursors" "$dmz_state"
"xcursor-themes" "X11 base cursors" "$xcursor_state"
"oxygencursors" "Oxygen cursors (KDE legacy)" "$oxygen_state"
)
fi
local item_count=${#items[@]}
local lista_alto=$((item_count > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count))
local choices
choices=$(whiptail --title "Cursor Themes" --checklist \
"Select cursor themes to install${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
"bibata-cursor-theme" "Bibata cursors$(_inst bibata-cursor-theme)" "$bibata_state" \
"breeze-cursor-theme" "Breeze cursors (KDE)$(_inst breeze-cursor-theme)" "$breeze_state" \
"chameleon-cursor-theme" "Chameleon cursors$(_inst chameleon-cursor-theme)" "$chameleon_state" \
"dmz-cursor-theme" "DMZ cursors$(_inst dmz-cursor-theme)" "$dmz_state" \
"xcursor-themes" "X11 base cursors$(_inst xcursor-themes)" "$xcursor_state" \
"oxygencursors" "Oxygen cursors (KDE legacy)$(_inst oxygencursors)" "$oxygen_state" \
3>&1 1>&2 2>&3)
choices=$(_checklist "Cursor Themes" "Select cursor themes to install${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $lista_alto \
"${items[@]}" \
)
clear
[ -z "$choices" ] && return
@@ -4,6 +4,8 @@
_cat_themes() {
local headless=false
_is_headless && headless=true
local -a items=()
if ! $headless; then
local arc_state; arc_state=$(_state "arc-theme")
local blackbird_state; blackbird_state=$(_state "blackbird-gtk-theme")
local bluebird_state; bluebird_state=$(_state "bluebird-gtk-theme")
@@ -11,18 +13,23 @@ _cat_themes() {
local greybird_state; greybird_state=$(_state "greybird-gtk-theme")
local numix_gtk_state; numix_gtk_state=$(_state "numix-gtk-theme")
local orchis_state; orchis_state=$(_state "orchis-gtk-theme")
items+=(
"arc-theme" "Arc GTK theme" "$arc_state"
"blackbird-gtk-theme" "Blackbird GTK theme" "$blackbird_state"
"bluebird-gtk-theme" "Bluebird GTK theme" "$bluebird_state"
"breeze-gtk-theme" "Breeze GTK theme (KDE port)" "$breeze_gtk_state"
"greybird-gtk-theme" "Greybird GTK theme" "$greybird_state"
"numix-gtk-theme" "Numix GTK theme" "$numix_gtk_state"
"orchis-gtk-theme" "Orchis GTK theme" "$orchis_state"
)
fi
local item_count=${#items[@]}
local lista_alto=$((item_count > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count))
local choices
choices=$(whiptail --title "Desktop Themes (GTK/KDE)" --checklist \
"Select desktop themes to install${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
"arc-theme" "Arc GTK theme$(_inst arc-theme)" "$arc_state" \
"blackbird-gtk-theme" "Blackbird GTK theme$(_inst blackbird-gtk-theme)" "$blackbird_state" \
"bluebird-gtk-theme" "Bluebird GTK theme$(_inst bluebird-gtk-theme)" "$bluebird_state" \
"breeze-gtk-theme" "Breeze GTK theme (KDE port)$(_inst breeze-gtk-theme)" "$breeze_gtk_state" \
"greybird-gtk-theme" "Greybird GTK theme$(_inst greybird-gtk-theme)" "$greybird_state" \
"numix-gtk-theme" "Numix GTK theme$(_inst numix-gtk-theme)" "$numix_gtk_state" \
"orchis-gtk-theme" "Orchis GTK theme$(_inst orchis-gtk-theme)" "$orchis_state" \
3>&1 1>&2 2>&3)
choices=$(_checklist "Desktop Themes (GTK/KDE)" "Select desktop themes to install${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $lista_alto \
"${items[@]}" \
)
clear
[ -z "$choices" ] && return
@@ -30,10 +37,6 @@ _cat_themes() {
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
for pkg in $cleaned; do
if $headless; then
echo "Skipping $pkg (headless mode)"
continue
fi
if ! is_installed "$pkg"; then
_run_install "$pkg"
else
+20 -11
View File
@@ -2,6 +2,10 @@
# fonts.sh — Fonts
_cat_fonts() {
local headless=false
_is_headless && headless=true
local -a items=()
if ! $headless; then
local bebas_state; bebas_state=$(_state "fonts-bebas-neue")
local anon_state; anon_state=$(_state "fonts-anonymous-pro")
local verana_state; verana_state=$(_state "fonts-adf-verana")
@@ -10,19 +14,24 @@ _cat_fonts() {
local mscore_state; mscore_state=$(_state "ttf-mscorefonts-installer")
local ubuntu_state; ubuntu_state=$(_state "fonts-ubuntu")
local recommended_state; recommended_state=$(_state "fonts-recommended")
items+=(
"fonts-bebas-neue" "Bebas Neue (display)" "$bebas_state"
"fonts-anonymous-pro" "Anonymous Pro (monospace)" "$anon_state"
"fonts-adf-verana" "ADF Verana (sans-serif)" "$verana_state"
"fonts-3270" "IBM 3270 terminal font" "$f3270_state"
"fonts-liberation" "Liberation (MS-compatible)" "$liberation_state"
"ttf-mscorefonts-installer" "Microsoft fonts (EULA required)" "$mscore_state"
"fonts-ubuntu" "Ubuntu font family" "$ubuntu_state"
"fonts-recommended" "Debian recommended fonts" "$recommended_state"
)
fi
local item_count=${#items[@]}
local lista_alto=$((item_count > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count))
local choices
choices=$(whiptail --title "Fonts" --checklist \
"Select fonts to install${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
"fonts-bebas-neue" "Bebas Neue (display)$(_inst fonts-bebas-neue)" "$bebas_state" \
"fonts-anonymous-pro" "Anonymous Pro (monospace)$(_inst fonts-anonymous-pro)" "$anon_state" \
"fonts-adf-verana" "ADF Verana (sans-serif)$(_inst fonts-adf-verana)" "$verana_state" \
"fonts-3270" "IBM 3270 terminal font$(_inst fonts-3270)" "$f3270_state" \
"fonts-liberation" "Liberation (MS-compatible)$(_inst fonts-liberation)" "$liberation_state" \
"ttf-mscorefonts-installer" "Microsoft fonts (EULA required)$(_inst ttf-mscorefonts-installer)" "$mscore_state" \
"fonts-ubuntu" "Ubuntu font family$(_inst fonts-ubuntu)" "$ubuntu_state" \
"fonts-recommended" "Debian recommended fonts$(_inst fonts-recommended)" "$recommended_state" \
3>&1 1>&2 2>&3)
choices=$(_checklist "Fonts" "Select fonts to install${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $lista_alto \
"${items[@]}" \
)
clear
[ -z "$choices" ] && return
+21 -23
View File
@@ -4,6 +4,8 @@
_cat_icons() {
local headless=false
_is_headless && headless=true
local -a items=()
if ! $headless; then
local breeze_state; breeze_state=$(_state "breeze-icon-theme")
local deepin_state; deepin_state=$(_state "deepin-icon-theme")
local ele_state; ele_state=$(_state "elementary-icon-theme")
@@ -17,34 +19,34 @@ _cat_icons() {
local suru_state; suru_state=$(_state "suru-icon-theme")
local kf6_state="OFF"
local has_kf6=false
if [ "$DEBIAN_CODENAME" = "trixie" ]; then
kf6_state=$(_state "kf6-breeze-icon-theme")
has_kf6=true
fi
local items=(
"breeze-icon-theme" "Breeze icon theme$(_inst breeze-icon-theme)" "$breeze_state"
"deepin-icon-theme" "Deepin icon theme$(_inst deepin-icon-theme)" "$deepin_state"
"elementary-icon-theme" "Elementary icon theme$(_inst elementary-icon-theme)" "$ele_state"
"elementary-xfce-icon-theme" "Elementary Xfce icons$(_inst elementary-xfce-icon-theme)" "$ele_xfce_state"
"moka-icon-theme" "Moka icon theme$(_inst moka-icon-theme)" "$moka_state"
"numix-icon-theme" "Numix icon theme$(_inst numix-icon-theme)" "$numix_state"
"numix-icon-theme-circle" "Numix Circle icon theme$(_inst numix-icon-theme-circle)" "$numix_c_state"
"obsidian-icon-theme" "Obsidian icon theme$(_inst obsidian-icon-theme)" "$obsidian_state"
"papirus-icon-theme" "Papirus icon theme$(_inst papirus-icon-theme)" "$papirus_state"
"paper-icon-theme" "Paper icon theme$(_inst paper-icon-theme)" "$paper_state"
"suru-icon-theme" "Suru icon theme$(_inst suru-icon-theme)" "$suru_state"
items=(
"breeze-icon-theme" "Breeze icon theme" "$breeze_state"
"deepin-icon-theme" "Deepin icon theme" "$deepin_state"
"elementary-icon-theme" "Elementary icon theme" "$ele_state"
"elementary-xfce-icon-theme" "Elementary Xfce icons" "$ele_xfce_state"
"moka-icon-theme" "Moka icon theme" "$moka_state"
"numix-icon-theme" "Numix icon theme" "$numix_state"
"numix-icon-theme-circle" "Numix Circle icon theme" "$numix_c_state"
"obsidian-icon-theme" "Obsidian icon theme" "$obsidian_state"
"papirus-icon-theme" "Papirus icon theme" "$papirus_state"
"paper-icon-theme" "Paper icon theme" "$paper_state"
"suru-icon-theme" "Suru icon theme" "$suru_state"
)
if $has_kf6; then
items+=("kf6-breeze-icon-theme" "KF6 Breeze icon theme$(_inst kf6-breeze-icon-theme)" "$kf6_state")
if [ "$DEBIAN_CODENAME" = "trixie" ]; then
items+=("kf6-breeze-icon-theme" "KF6 Breeze icon theme" "$kf6_state")
fi
fi
local item_count=${#items[@]}
local lista_alto=$((item_count > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count))
local choices
choices=$(whiptail --title "Icon Themes" --checklist \
"Select icon themes to install${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
choices=$(_checklist "Icon Themes" "Select icon themes to install${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $lista_alto \
"${items[@]}" \
3>&1 1>&2 2>&3)
)
clear
[ -z "$choices" ] && return
@@ -52,10 +54,6 @@ _cat_icons() {
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
for pkg in $cleaned; do
if $headless; then
echo "Skipping $pkg (headless mode)"
continue
fi
if ! is_installed "$pkg"; then
_run_install "$pkg"
else
+2 -4
View File
@@ -2,15 +2,13 @@
# themes.sh — Customization submenu dispatcher
_cat_customization() {
local TUI_ANCHO_REFORZADO=$((TUI_ANCHO + 6))
local sub
sub=$(whiptail --title "Customization System" --menu \
"Select type:" $TUI_ALTO $TUI_ANCHO_REFORZADO $TUI_ALTO_LISTA \
sub=$(_menu "Customization System" "Select type:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
"1" "Desktop Themes (GTK/KDE)" \
"2" "Icon Themes" \
"3" "Cursor Themes" \
"4" "Fonts" \
3>&1 1>&2 2>&3)
)
[ -z "$sub" ] && return
case $sub in
1) _cat_themes ;;
+78 -6
View File
@@ -130,7 +130,7 @@ _is_broadcom_b43() {
local dec=$((16#$id))
if [ "$dec" -ge $((16#4301)) ] && [ "$dec" -le $((16#4331)) ]; then return 0; fi
if [ "$dec" -ge $((16#4336)) ] && [ "$dec" -le $((16#4338)) ]; then return 0; fi
case "$id" in 4352|4357|4358|4360|4727) return 0 ;; esac
case "$id" in 4352) return 0 ;; esac
return 1
}
@@ -186,7 +186,7 @@ _build_firmware_plan() {
if is_installed bluez; then
plan+=" [+] bluez (already installed)\n"
else
plan+=" [+] bluez + bluez-utils + bluez-obexd (base stack)\n"
plan+=" [+] bluez + bluez-tools + bluez-obexd (base stack)\n"
fi
case "${DESKTOP_ENV:-other}" in
kde) plan+=" [+] bluedevil (KDE applet)\n"
@@ -255,8 +255,22 @@ _handle_wireless() {
fi
installed_any=true
elif _is_broadcom_b43 "$dev_id"; then
if ! dpkg -l firmware-b43-installer >/dev/null 2>&1; then
_run_install_pkg firmware-b43-installer
fi
if [ ! -d /lib/firmware/b43 ] || [ -z "$(ls -A /lib/firmware/b43 2>/dev/null)" ]; then
_msg "b43 Firmware Warning" \
"The firmware-b43-installer package was installed, but the\n\
proprietary firmware download appears to have failed\n\
(no files found in /lib/firmware/b43).\n\n\
To fix this, connect a wired network and run:\n\
sudo dpkg-reconfigure firmware-b43-installer\n\n\
After the firmware is downloaded, reboot the system." 14 75
_pause
else
installed_any=true
fi
elif _is_broadcom_b43legacy "$dev_id"; then
_run_install_pkg firmware-b43legacy-installer
installed_any=true
@@ -264,10 +278,36 @@ _handle_wireless() {
local bcm_ver header_ver
bcm_ver=$(apt-cache policy broadcom-sta-dkms 2>/dev/null | awk 'NR==3 {print $2; exit}')
header_ver=$(apt-cache policy linux-headers-$(uname -r) 2>/dev/null | awk 'NR==3 {print $2; exit}')
if ! apt-cache policy "linux-headers-$(uname -r)" 2>/dev/null | grep -q "Candidate: [^ (none)]"; then
_msg "Broadcom Error" \
"linux-headers-$(uname -r) not available.\n\nCannot compile broadcom-sta-dkms without kernel headers." 10 60
_pause
continue
fi
if _confirm "Broadcom WiFi" "Install Broadcom driver?\n\nRequired for this chipset. Compiles a kernel module.\n\n broadcom-sta-dkms ${bcm_ver:-unknown}\n linux-headers-$(uname -r) ${header_ver:-unknown}\n\nProceed?"; then
_run_cmd "Broadcom" "sudo DEBIAN_FRONTEND=noninteractive apt install -y linux-headers-$(uname -r) broadcom-sta-dkms" \
"Installing Broadcom driver..."
local has_broadcom_bt=false
for btdev in "${PCI_BT_DEVS[@]}"; do
if echo "$btdev" | grep -qi 'broadcom'; then
has_broadcom_bt=true
break
fi
done
if $has_broadcom_bt; then
echo -e "${YELLOW}Broadcom combo card (WiFi + Bluetooth) detected.${NC}"
cat > /etc/modprobe.d/broadcom-combo.conf <<'EOF'
# Broadcom combo: ensure btusb loads after wl
softdep wl post: btusb
EOF
echo -e "${YELLOW}A reboot may be required for Bluetooth to work correctly.${NC}"
fi
echo "Broadcom proprietary driver installed. A reboot may be required."
_pause
installed_any=true
fi
fi
@@ -281,17 +321,48 @@ _handle_wireless() {
if ! $installed_any; then
echo "No special WiFi firmware needed -- base firmware-linux-nonfree covers this system."
_pause
fi
}
# ── Ensure non-free repository is enabled ──
_ensure_nonfree_repo() {
local nonfree_found=false
if [ -f /etc/apt/sources.list ] && grep -Eq '^[^#]*\bnon-free\b' /etc/apt/sources.list 2>/dev/null; then
nonfree_found=true
fi
if ! $nonfree_found && [ -d /etc/apt/sources.list.d ]; then
if grep -qr 'Components:.*\bnon-free\b' /etc/apt/sources.list.d/*.sources 2>/dev/null; then
nonfree_found=true
fi
fi
if $nonfree_found; then
return 0
fi
if _confirm "non-free Repository" "Component 'non-free' (and 'non-free-firmware') is required for WiFi/Bluetooth/GPU firmware.\n\nAdd them to your APT repositories?"; then
if [ -f /etc/apt/sources.list ]; then
sudo sed -i '/^deb / { /non-free/! s/\(main[^ ]*\)/\1 non-free non-free-firmware/ }' /etc/apt/sources.list
fi
if [ -d /etc/apt/sources.list.d ]; then
for f in /etc/apt/sources.list.d/*.sources; do
[ -f "$f" ] || continue
sudo sed -i '/^Components:/ { /non-free/! s/$/ non-free non-free-firmware/ }' "$f"
done
fi
sudo apt update
echo -e "${GREEN}non-free repository enabled.${NC}"
return 0
fi
return 1
}
# ── Main entry point ──
install_firmware() {
echo -e "${YELLOW}Base firmware check...${NC}"
if ! grep -qr "non-free" /etc/apt/sources.list /etc/apt/sources.list.d/ 2>/dev/null; then
_msg "Error" "Error: No 'non-free' repositories were detected.\n\
Please first run the 'Configure repositories' option in the\n\
main menu to install proprietary firmwares." 10 65
if ! _ensure_nonfree_repo; then
_msg "Error" "No 'non-free' repositories were enabled and the user declined to add them.\nPlease enable non-free manually or accept the prompt in the Firmware option." 10 65
return 1
fi
@@ -366,4 +437,5 @@ main menu to install proprietary firmwares." 10 65
# 8. Summary
echo -e "${GREEN}Network & firmware setup complete.${NC}"
_pause
}
+39 -99
View File
@@ -49,122 +49,61 @@ ensure_contrib_repo() {
install_gaming() {
echo -e "${YELLOW}Gaming setup...${NC}"
# 1. 32-bit support prompt FIRST
local enable_32bit=false
if _confirm "32-bit Support" "Enable i386 architecture for 32-bit games?\n\nRequired by Steam/Proton for 32-bit games.\nInstalls matching 32-bit graphics drivers."; then
enable_32bit=true
fi
if $enable_32bit; then
echo "Enabling 32-bit architecture (i386)..."
if ! dpkg --print-foreign-architectures | grep -q i386; then
sudo dpkg --add-architecture i386
fi
_run_cmd "APT Update" "sudo apt update" "Updating package lists..."
echo "Installing 32-bit graphics drivers..."
if [ "$GPU_TYPE" = "nvidia" ]; then
case "${NVIDIA_DRIVER_MODE:-stable}" in
cuda-repo)
local nv32_pkg="nvidia-driver-libs:i386"
local nv32_ver
nv32_ver=$(dpkg -l "$nv32_pkg" 2>/dev/null | awk '/^ii/ {print $3}')
if [ -z "$nv32_ver" ] || ! echo "$nv32_ver" | grep -q "^590"; then
local msg="Source: NVIDIA CUDA Repository (Pinned v590)\n"
msg+="NVIDIA 32-bit Libraries (v590 branch)\n\n"
msg+="[+] nvidia-driver-libs:i386"
if _confirm "NVIDIA 32-bit" "$msg" 12 70; then
_run_cmd "32-bit NVIDIA" \
"sudo apt install -y ${nv32_pkg}" \
"Installing 32-bit NVIDIA libraries from CUDA repo..."
fi
else
_msg "NVIDIA 32-bit" \
"32-bit NVIDIA CUDA libraries already deployed.\n\nv590 ${nv32_ver}" 10 70
fi
;;
backports)
local nv32_pkg="nvidia-driver-libs:i386"
local nv32_ver
nv32_ver=$(apt-cache policy "$nv32_pkg" 2>/dev/null | awk 'NR==3 {print $2; exit}')
local msg="Source: Debian ${DEBIAN_CODENAME^}-Backports\n"
msg+="NVIDIA 32-bit Libraries ${nv32_ver:-unknown}\n\n"
msg+="[+] nvidia-driver-libs:i386"
if _confirm "NVIDIA 32-bit" "$msg" 12 70; then
_run_cmd "32-bit NVIDIA" "sudo apt install -y -t ${DEBIAN_CODENAME}-backports ${nv32_pkg}" \
"Installing 32-bit NVIDIA drivers from backports..."
fi
;;
stable)
local nv32_pkg="nvidia-driver-libs:i386"
local nv32_ver
nv32_ver=$(apt-cache policy "$nv32_pkg" 2>/dev/null | awk 'NR==3 {print $2; exit}')
local use_bpo32=false
if [ "$(is_backports_enabled)" == "true" ]; then
local bpo_nv32_ver
bpo_nv32_ver=$(apt-cache madison "$nv32_pkg" 2>/dev/null | \
grep "${DEBIAN_CODENAME}-backports" | awk '{print $3}' | head -1)
if [ -n "$bpo_nv32_ver" ]; then
local msg="Source: Debian ${DEBIAN_CODENAME^} (Backports available)\n"
msg+="NVIDIA 32-bit Libraries: ${nv32_pkg}\n\n"
msg+=" Backports: ${bpo_nv32_ver}\n"
msg+=" Stable: ${nv32_ver:-unknown}\n\n"
msg+="Choose version:"
if _confirm_custom "NVIDIA 32-bit" "$msg" "Backports" "Stable" 14 70; then
use_bpo32=true
fi
fi
fi
if $use_bpo32; then
_run_cmd "32-bit NVIDIA" "sudo apt install -y -t ${DEBIAN_CODENAME}-backports ${nv32_pkg}" \
"Installing 32-bit NVIDIA drivers from backports..."
else
local msg="Source: Debian ${DEBIAN_CODENAME^} Stable\n"
msg+="NVIDIA 32-bit Libraries ${nv32_ver:-unknown}\n\n"
msg+="[+] nvidia-driver-libs:i386"
if _confirm "NVIDIA 32-bit" "$msg" 12 70; then
_run_cmd "32-bit NVIDIA" "sudo apt install -y ${nv32_pkg}" \
"Installing 32-bit NVIDIA drivers..."
fi
fi
;;
esac
else
_install_mesa_32bit
fi
fi
# 2. Gaming packages checklist
# 1. Single checklist with ALL options (including i386 toggle)
local choices
choices=$(whiptail --title "Gaming Setup" --checklist \
choices=$(_checklist "Gaming Setup" \
"Select gaming packages to install${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
"steam" "Steam (requires 32-bit support)" ON \
"gamemode" "Game performance optimization" ON \
"mangohud" "Performance overlay (Vulkan/OpenGL)" ON \
"heroic" "Heroic Launcher (Epic/GOG)" OFF \
"java" "Java Runtimes (8, 17, 21)" OFF \
"goverlay" "MangoHud config GUI" ON \
"openrgb" "OpenRGB (RGB lighting control)$(_inst openrgb)" OFF \
"lutris" "Game launcher/manager" OFF \
"retroarch" "RetroArch Emulator Frontend$(_inst retroarch)" OFF \
3>&1 1>&2 2>&3)
"heroic" "Heroic Launcher (Epic/GOG)" OFF \
"java" "Minecraft Java Runtime" OFF \
"openrgb" "OpenRGB (RGB lighting control)" OFF \
"lutris" "Lutris + Wine (requires 32-bit support)" OFF \
"retroarch" "RetroArch Emulator Frontend" OFF \
"i386" "Enable 32-bit (i386) architecture" ON)
if [ -z "$choices" ]; then
echo "No gaming packages selected."
_pause
return
fi
local cleaned
cleaned=$(echo "$choices" | tr -d '"')
# 3. Warn if Steam selected without 32-bit
if echo "$cleaned" | grep -qw "steam" && ! $enable_32bit; then
echo -e "${YELLOW}Warning: Steam requires 32-bit support.${NC}"
echo "Installation may fail. Re-run this option and enable 32-bit support."
# 2. Determine if 32-bit is needed (steam, lutris, or explicit i386 toggle)
local need_32bit=false
for p in $cleaned; do
case $p in steam|lutris) need_32bit=true ;; esac
done
echo "$cleaned" | grep -qw i386 && need_32bit=true
# Strip pseudo-entry "i386" from the install list
local install_list
install_list=$(echo "$cleaned" | tr ' ' '\n' | grep -v '^i386$' | tr '\n' ' ')
install_list=${install_list% }
# 3. Enable i386 architecture if needed
if $need_32bit && ! dpkg --print-foreign-architectures 2>/dev/null | grep -q i386; then
echo -e "${YELLOW}Enabling i386 architecture (required by selection)...${NC}"
sudo dpkg --add-architecture i386
_run_cmd "APT Update" "sudo apt update" "Updating package lists..."
fi
# 4. Install selected packages
for pkg in $cleaned; do
# 4. Install 32-bit graphics drivers only if 32-bit is needed
if $need_32bit; then
echo "Installing 32-bit graphics drivers..."
if [ "$GPU_TYPE" = "nvidia" ]; then
_install_nvidia_32bit
else
_install_mesa_32bit
fi
fi
# 5. Install selected packages
for pkg in $install_list; do
case $pkg in
steam)
if ensure_contrib_repo; then
@@ -192,4 +131,5 @@ install_gaming() {
done
echo -e "${GREEN}Gaming setup complete.${NC}"
_pause
}
+64 -50
View File
@@ -2,66 +2,80 @@
# Shared helpers for gaming submodules
_install_mesa_32bit() {
local mesa_pkgs=(
"mesa-vulkan-drivers" "mesa-vulkan-drivers:i386"
"libgl1-mesa-dri" "libgl1-mesa-dri:i386"
"libglx-mesa0" "libglx-mesa0:i386"
"libegl-mesa0" "libegl-mesa0:i386"
"mesa-va-drivers" "mesa-va-drivers:i386"
local base_pkgs=(
"mesa-vulkan-drivers"
"libgl1-mesa-dri"
"libglx-mesa0"
"libegl-mesa0"
"mesa-va-drivers"
"mesa-libgallium"
)
local ref_ver
ref_ver=$(apt-cache policy mesa-vulkan-drivers:i386 2>/dev/null | awk 'NR==3 {print $2; exit}')
local ref_bpo_ver
ref_bpo_ver=$(apt-cache madison mesa-vulkan-drivers:i386 2>/dev/null | \
grep "${DEBIAN_CODENAME}-backports" | awk '{print $3}' | head -1)
local comp_line="Components: Vulkan:i386, OpenGL:i386, GLX:i386, EGL:i386, VA-API:i386"
local i386_active=false
dpkg --print-foreign-architectures 2>/dev/null | grep -q i386 && i386_active=true
if [ "$(is_backports_enabled)" == "true" ] && [ -n "$ref_bpo_ver" ]; then
local bpo_pkgs=()
local stable_pkgs=()
local install_list=()
for mpkg in "${mesa_pkgs[@]}"; do
local bpo_ver
bpo_ver=$(apt-cache madison "$mpkg" 2>/dev/null | \
grep "${DEBIAN_CODENAME}-backports" | awk '{print $3}' | head -1)
if [ -n "$bpo_ver" ]; then
bpo_pkgs+=("$mpkg")
else
stable_pkgs+=("$mpkg")
for p in "${base_pkgs[@]}"; do
if apt-cache show "$p" >/dev/null 2>&1; then
install_list+=("$p")
fi
if $i386_active && apt-cache show "${p}:i386" >/dev/null 2>&1; then
install_list+=("${p}:i386")
fi
done
local src_label="Debian ${DEBIAN_CODENAME^}-Backports"
[ ${#stable_pkgs[@]} -gt 0 ] && src_label+=" + Stable"
if [ ${#install_list[@]} -eq 0 ]; then
echo "No Mesa 32-bit packages available for installation."
return
fi
local msg="Mesa 32-bit drivers required for gaming.\n\n"
msg+="Source: ${src_label}\n"
msg+="Mesa ${ref_bpo_ver:-$ref_ver}\n"
msg+="${comp_line}\n\n"
[ ${#stable_pkgs[@]} -gt 0 ] && msg+="Some packages only available in stable.\n"
msg+="Choose version:"
_run_cmd "Mesa 32-bit" "sudo apt install -y ${install_list[*]}" \
"Installing Mesa drivers (${#install_list[@]} packages)..."
echo -e "${GREEN}Mesa 32-bit libraries installed.${NC}"
}
if _confirm_custom "Mesa 32-bit" "$msg" "Backports" "Stable" 14 70; then
_run_cmd "Mesa 32-bit" "sudo apt install -y -t ${DEBIAN_CODENAME}-backports ${bpo_pkgs[*]}" \
"Installing 32-bit Mesa from backports..."
if [ ${#stable_pkgs[@]} -gt 0 ]; then
_run_cmd "Mesa 32-bit" "sudo apt install -y ${stable_pkgs[*]}" \
"Installing remaining 32-bit Mesa from stable..."
apt_cache_exists() {
apt-cache show "$1" >/dev/null 2>&1
}
_detect_installed_nvidia_driver() {
dpkg -l 2>/dev/null | awk '
/^ii/ && ($2=="nvidia-driver" || $2=="nvidia-open" ||
$2 ~ /^nvidia-legacy-[0-9]+xx-driver$/ ||
$2 ~ /^nvidia-tesla-[0-9]+-driver$/) {print $2; exit}'
}
_nvidia_libs_pkg() {
case "$1" in
nvidia-driver|nvidia-open) echo "nvidia-driver-libs" ;;
*) echo "${1}-libs" ;;
esac
}
_install_nvidia_32bit() {
local drv_pkg
drv_pkg=$(_detect_installed_nvidia_driver)
if [ -z "$drv_pkg" ]; then
_msg "NVIDIA 32-bit" \
"No NVIDIA driver detected.\n\nRun Graphics Drivers (option 5) first,\nthen return to add 32-bit libraries." 10 60
return 0
fi
else
_run_cmd "Mesa 32-bit" "sudo apt install -y ${mesa_pkgs[*]}" \
"Installing 32-bit Mesa from stable..."
fi
else
local msg="Mesa 32-bit drivers required for gaming.\n\n"
msg+="Source: Debian Stable\n"
msg+="Mesa ${ref_ver}\n"
msg+="${comp_line}\n\n"
msg+="Install Mesa 32-bit drivers?"
if _confirm "Mesa 32-bit" "$msg" 14 70; then
_run_cmd "Mesa 32-bit" "sudo apt install -y ${mesa_pkgs[*]}" \
"Installing 32-bit Mesa..."
local drv_ver
drv_ver=$(dpkg -s "$drv_pkg" 2>/dev/null | sed -n 's/^Version: //p')
local libs_pkg
libs_pkg=$(_nvidia_libs_pkg "$drv_pkg")
if ! apt_cache_exists "${libs_pkg}:i386"; then
_msg "NVIDIA 32-bit" \
"No ${libs_pkg}:i386 available for your driver (${drv_pkg}).\nSkipping 32-bit NVIDIA libraries." 10 60
return 0
fi
if _confirm "NVIDIA 32-bit" \
"Driver: ${drv_pkg} ${drv_ver}\n\nInstall ${libs_pkg}:i386 (same version to prevent ABI mismatch)." 12 70; then
_run_cmd "NVIDIA 32-bit" "sudo apt install -y ${libs_pkg}:i386=${drv_ver}" \
"Installing 32-bit NVIDIA libraries (${drv_ver})..."
fi
}
+31 -11
View File
@@ -3,17 +3,37 @@
install_heroic() {
local heroic_deb="/tmp/heroic.deb"
_run_cmd "Heroic" "sudo apt install -y curl wget" "Installing dependencies..."
local gh_url
gh_url=$(curl -s --connect-timeout 10 https://api.github.com/repos/Heroic-Games-Launcher/\
HeroicGamesLauncher/releases/latest | \
grep -oP 'https://[^"]+amd64\.deb' | head -1)
if [ -z "$gh_url" ]; then
echo -e "${RED}Could not determine latest Heroic release.${NC}"
else
_run_cmd "Heroic" "wget -O $heroic_deb $gh_url" "Downloading Heroic..."
_run_cmd "Heroic" "sudo apt install -y $heroic_deb" "Installing Heroic..."
local ua="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
_run_cmd "Heroic" "sudo apt install -y curl jq" "Installing dependencies..."
local json
json=$(curl -s --connect-timeout 10 -H "User-Agent: $ua" \
"https://api.github.com/repos/Heroic-Games-Launcher/HeroicGamesLauncher/releases/latest") || {
_msg "Heroic Error" "Could not fetch release data from GitHub API." 8 60
return 1
}
local deb_url
deb_url=$(echo "$json" | jq -r '
.assets[] | select(.name | endswith("amd64.deb")) | .browser_download_url
' 2>/dev/null || true)
if [ -z "$deb_url" ]; then
_msg "Heroic Error" "Could not find amd64.deb asset in latest release." 10 60
return 1
fi
_run_cmd "Heroic" "curl -sL -H 'User-Agent: $ua' -o '$heroic_deb' '$deb_url'" "Downloading Heroic..."
if ! dpkg-deb --info "$heroic_deb" >/dev/null 2>&1; then
_msg "Heroic Error" "Downloaded .deb is corrupted or truncated.\n\nRemoving file." 10 60
rm -f "$heroic_deb"
return 1
fi
echo -e "${GREEN}Package integrity verified.${NC}"
_run_cmd "Heroic" "sudo apt install -y '$heroic_deb'" "Installing Heroic..."
rm -f "$heroic_deb"
echo -e "${GREEN}Heroic Games Launcher installed.${NC}"
fi
}
+55 -22
View File
@@ -2,11 +2,11 @@
# Gaming performance tools installation
install_mangohud() {
_run_cmd "MangoHud" "sudo apt install -y mangohud" "Installing MangoHud..."
local pkgs="mangohud"
if dpkg --print-foreign-architectures | grep -q i386; then
echo "Installing 32-bit MangoHud..."
_run_cmd "MangoHud" "sudo apt install -y mangohud:i386" "Installing 32-bit MangoHud..."
pkgs+=" mangohud:i386"
fi
_run_cmd "MangoHud" "sudo apt install -y $pkgs" "Installing MangoHud (64 + 32-bit)..."
}
install_gamemode() {
@@ -18,37 +18,70 @@ install_goverlay() {
}
install_lutris() {
_run_install lutris
local pkgs="lutris wine64"
if dpkg --print-foreign-architectures 2>/dev/null | grep -q i386; then
pkgs+=" wine32"
fi
_run_cmd "Lutris" "sudo apt install -y $pkgs" "Installing Lutris + Wine..."
}
install_openrgb() {
local url
if [ "$DEBIAN_VERSION" = "12" ]; then
url="https://codeberg.org/OpenRGB/OpenRGB/releases/download/release_candidate_1.0rc2/openrgb_1.0rc2_amd64_bookworm_0fca93e.deb"
elif [ "$DEBIAN_VERSION" = "13" ]; then
url="https://codeberg.org/OpenRGB/OpenRGB/releases/download/release_candidate_1.0rc2/openrgb_1.0rc2_amd64_trixie_0fca93e.deb"
else
local deb_suffix
case "$DEBIAN_CODENAME" in
bookworm) deb_suffix="bookworm" ;;
trixie) deb_suffix="trixie" ;;
*)
echo "OpenRGB requires Debian 12 (Bookworm) or 13 (Trixie)."
return 1
fi
;;
esac
local deb_path="/tmp/openrgb.deb"
local ua="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
_run_cmd "OpenRGB" "curl -L -o ${deb_path} -A '${ua}' '${url}'" "Downloading OpenRGB..."
_run_cmd "OpenRGB" "sudo apt install -y curl jq" "Installing dependencies..."
if [ ! -s "${deb_path}" ]; then
echo -e "${RED}[-]${NC} Download failed: empty or missing file."
rm -f "${deb_path}"
local json
json=$(curl -s --connect-timeout 10 \
"https://codeberg.org/api/v1/repos/OpenRGB/OpenRGB/releases?limit=1") || {
echo -e "${RED}Could not fetch OpenRGB releases from Codeberg API.${NC}"
return 1
}
local deb_url sha256
while IFS=' ' read -r url hash; do
deb_url="$url"
sha256="$hash"
done < <(echo "$json" | jq -r '
.[0].assets[] | select(.name | contains("amd64_'"${deb_suffix}"'.deb")) |
"\(.browser_download_url) \(.sha256 // "")"
' 2>/dev/null)
if [ -z "$deb_url" ]; then
echo -e "${RED}Could not find OpenRGB .deb for ${DEBIAN_CODENAME^}.${NC}"
return 1
fi
echo -e "${GREEN}[+]${NC} Installing OpenRGB package..."
if ! sudo apt install -y "${deb_path}"; then
rm -f "${deb_path}"
echo -e "${RED}[-]${NC} Package installation failed."
_run_cmd "OpenRGB" "curl -L -o '${deb_path}' -A '${ua}' '${deb_url}'" "Downloading OpenRGB..."
if [ -n "$sha256" ]; then
if ! echo "$sha256 $deb_path" | sha256sum -c --strict; then
echo -e "${RED}SHA256 mismatch! Downloaded file may be corrupted. Removing.${NC}"
rm -f "$deb_path"
return 1
fi
echo -e "${GREEN}SHA256 verified.${NC}"
else
if ! dpkg-deb --info "$deb_path" >/dev/null 2>&1; then
echo -e "${RED}Downloaded .deb is corrupted. Removing.${NC}"
rm -f "$deb_path"
return 1
fi
echo -e "${YELLOW}No SHA256 in API, validated via dpkg-deb.${NC}"
fi
sudo apt install -y "$deb_path"
rm -f "$deb_path"
sudo modprobe i2c-dev
if ! grep -q "^i2c-dev" /etc/modules 2>/dev/null; then
@@ -58,8 +91,8 @@ install_openrgb() {
sudo udevadm control --reload-rules && sudo udevadm trigger
sudo setcap cap_sys_rawio=ep /usr/bin/openrgb 2>/dev/null || true
rm -f "${deb_path}"
echo -e "${GREEN}OpenRGB installed. NOTE: You must reboot or log out/in for the 'i2c' group to take effect.${NC}"
echo -e "${GREEN}OpenRGB installed. Reboot or log out/in for i2c group to take effect.${NC}"
_pause
}
install_retroarch() {
@@ -86,5 +119,5 @@ install_retroarch() {
echo " Please check our repository's documentation or visit:"
echo " https://wiki.debian.org/RetroArch"
echo "================================================================="
read -p "Press ENTER to continue..."
_pause
}
+7 -3
View File
@@ -105,13 +105,17 @@ install_gpu_drivers() {
else
install_nvidia_driver
fi
elif [ "$(is_nvidia_fermi)" = "true" ]; then
_msg "NVIDIA Fermi — Bookworm" \
"Fermi GPUs (GF1xx) are not supported\nin Debian 12 (Bookworm).\nThe nvidia-legacy-390xx driver is\nnot available in this version.\n\nNo NVIDIA driver will be installed."
NVIDIA_DRIVER_MODE=""
else
install_nvidia_driver
fi
elif [ "$DEBIAN_VERSION" = "13" ]; then
if [ "$(is_nvidia_kepler)" = "true" ]; then
_msg "NVIDIA Kepler — Trixie" \
"Your GPU is NVIDIA Kepler architecture.\nThe nvidia-tesla-470 driver is not available\nin Debian 13 (Trixie).\n\nNo NVIDIA driver will be installed for this GPU.\nOther GPUs (Intel/AMD) will still be configured."
if [ "$(is_nvidia_kepler)" = "true" ] || [ "$(is_nvidia_fermi)" = "true" ]; then
_msg "NVIDIA — Trixie" \
"Kepler and Fermi GPUs are not supported\nin Debian 13 (Trixie).\n\nThe nvidia-legacy drivers are not available\nin this version of Debian.\n\nNo NVIDIA driver will be installed."
NVIDIA_DRIVER_MODE=""
else
install_nvidia_driver
+54 -24
View File
@@ -15,12 +15,45 @@ is_nvidia_kepler() {
if [ "$dev_int" -ge $((16#1000)) ] && [ "$dev_int" -le $((16#103F)) ]; then echo true; return; fi
# Bloque 3: GK104/GK106 (completo) — 0x1180..0x11FF
if [ "$dev_int" -ge $((16#1180)) ] && [ "$dev_int" -le $((16#11FF)) ]; then echo true; return; fi
# Bloque 4: GK208/GK208B acotado — 0x1280..0x12BF
# Bloque 4: GK208/GK208B (completo) — 0x1280..0x12BF
if [ "$dev_int" -ge $((16#1280)) ] && [ "$dev_int" -le $((16#12BF)) ]; then echo true; return; fi
echo false
}
is_nvidia_fermi() {
local dev_id
dev_id=$(lspci -nn | grep -iE "VGA|3D" | grep -i nvidia | grep -oP '10de:\K[0-9a-fA-F]+' | head -n1)
[ -z "$dev_id" ] && { echo false; return; }
local dev_int
dev_int=$((16#${dev_id,,}))
# GF100 / GF110 — GTX 480, GTX 580, Quadro 6000, Tesla C2050
if [ "$dev_int" -ge $((16#06C0)) ] && [ "$dev_int" -le $((16#06DF)) ]; then echo true; return; fi
# GF104 / GF114 — GTS 450, GTX 460M, GT 555M
if [ "$dev_int" -ge $((16#0DC0)) ] && [ "$dev_int" -le $((16#0DCF)) ]; then echo true; return; fi
# GF104 / GF108 — GT 445M, GT 435M, GT 550M
if [ "$dev_int" -ge $((16#0DD0)) ] && [ "$dev_int" -le $((16#0DDF)) ]; then echo true; return; fi
# GF108 — GT 440, GT 430, GT 520, GT 610, GT 620M, NVS 5400M
if [ "$dev_int" -ge $((16#0DE0)) ] && [ "$dev_int" -le $((16#0DEF)) ]; then echo true; return; fi
# GF108 — GT 525M, GT 540M, GT 550M, Quadro 600, Quadro 500M
if [ "$dev_int" -ge $((16#0DF0)) ] && [ "$dev_int" -le $((16#0DFF)) ]; then echo true; return; fi
# GF104 / GF114 — GTX 460, GTX 470M, GTX 485M
if [ "$dev_int" -ge $((16#0E22)) ] && [ "$dev_int" -le $((16#0E31)) ]; then echo true; return; fi
# GF119 — GT 520M, GT 610M, NVS 4200M
if [ "$dev_int" -ge $((16#1050)) ] && [ "$dev_int" -le $((16#105F)) ]; then echo true; return; fi
# GF110 — GTX 580, GTX 570, GTX 560 Ti, GTX 590
if [ "$dev_int" -ge $((16#1080)) ] && [ "$dev_int" -le $((16#108F)) ]; then echo true; return; fi
# GF110 — Tesla M2090, Quadro 5010M, Quadro 7000
if [ "$dev_int" -ge $((16#1090)) ] && [ "$dev_int" -le $((16#109F)) ]; then echo true; return; fi
# GF116 / GF119 — GTX 560, GTX 460 v2, GTX 555, GT 645
if [ "$dev_int" -ge $((16#1200)) ] && [ "$dev_int" -le $((16#120F)) ]; then echo true; return; fi
# GF116 / GF108 — GTX 550 Ti, GTS 450 rev, GT 545, GT 640 (Fermi)
if [ "$dev_int" -ge $((16#1240)) ] && [ "$dev_int" -le $((16#124F)) ]; then echo true; return; fi
echo false
}
is_nvidia_maxwell() {
local dev_id
dev_id=$(lspci -nn | grep -iE "VGA|3D" | grep -i nvidia | grep -oP '10de:\K[0-9a-fA-F]+' | head -n1)
@@ -29,16 +62,14 @@ is_nvidia_maxwell() {
local dev_int
dev_int=$((16#${dev_id,,}))
# GM108 (GT 830M, GT 840M, GT 940M)
if [ "$dev_int" -ge $((16#1340)) ] && [ "$dev_int" -le $((16#134F)) ]; then echo true; return; fi
# GM107 (GTX 750 Ti, GTX 860M)
if [ "$dev_int" -ge $((16#1380)) ] && [ "$dev_int" -le $((16#138F)) ]; then echo true; return; fi
# GM200 (TITAN X, GTX 980 Ti)
if [ "$dev_int" -ge $((16#13C0)) ] && [ "$dev_int" -le $((16#13CF)) ]; then echo true; return; fi
# GM204 (GTX 980, GTX 970)
if [ "$dev_int" -ge $((16#13D0)) ] && [ "$dev_int" -le $((16#13DF)) ]; then echo true; return; fi
# GM206 (GTX 960, GTX 950)
if [ "$dev_int" -ge $((16#1480)) ] && [ "$dev_int" -le $((16#148F)) ]; then echo true; return; fi
# GM108/GM107/GM204 — gama media/baja + Quadros M (incluye 980M/970M)
if [ "$dev_int" -ge $((16#1340)) ] && [ "$dev_int" -le $((16#13FF)) ]; then echo true; return; fi
# GM206 — GTX 960, GTX 950, Quadro M2000
if [ "$dev_int" -ge $((16#1400)) ] && [ "$dev_int" -le $((16#14FF)) ]; then echo true; return; fi
# GM200 TITAN X, GTX 980 Ti
if [ "$dev_int" -ge $((16#17C0)) ] && [ "$dev_int" -le $((16#17CF)) ]; then echo true; return; fi
# GM200 profesional — Quadro M6000, Tesla M40
if [ "$dev_int" -ge $((16#17F0)) ] && [ "$dev_int" -le $((16#17FF)) ]; then echo true; return; fi
echo false
}
@@ -51,18 +82,16 @@ is_nvidia_pascal() {
local dev_int
dev_int=$((16#${dev_id,,}))
# GP100 (Tesla P100, Quadro GP100)
# GP100 Tesla P100, Quadro GP100
if [ "$dev_int" -ge $((16#15F0)) ] && [ "$dev_int" -le $((16#15FF)) ]; then echo true; return; fi
# GP104 (GTX 1080, GTX 1070)
if [ "$dev_int" -ge $((16#1B00)) ] && [ "$dev_int" -le $((16#1B1F)) ]; then echo true; return; fi
# GP102 (TITAN Xp, GTX 1080 Ti)
if [ "$dev_int" -ge $((16#1B80)) ] && [ "$dev_int" -le $((16#1B8F)) ]; then echo true; return; fi
# GP106 (GTX 1060)
if [ "$dev_int" -ge $((16#1C00)) ] && [ "$dev_int" -le $((16#1C2F)) ]; then echo true; return; fi
# GP107 (GTX 1050 Ti, GTX 1050)
if [ "$dev_int" -ge $((16#1C80)) ] && [ "$dev_int" -le $((16#1C8F)) ]; then echo true; return; fi
# GP108 (GT 1030, GT 1010)
if [ "$dev_int" -ge $((16#1D00)) ] && [ "$dev_int" -le $((16#1DFF)) ]; then echo true; return; fi
# GP102 — TITAN Xp, GTX 1080 Ti, Tesla P40, Quadro P6000
if [ "$dev_int" -ge $((16#1B00)) ] && [ "$dev_int" -le $((16#1B3F)) ]; then echo true; return; fi
# GP104 — GTX 1080, GTX 1070, Quadro P5000/P4000/P5200/P4200
if [ "$dev_int" -ge $((16#1B80)) ] && [ "$dev_int" -le $((16#1BBF)) ]; then echo true; return; fi
# GP106 + GP107 — GTX 1060, GTX 1050 Ti, GTX 1050, Quadro P2000/P1000/P620/P600
if [ "$dev_int" -ge $((16#1C00)) ] && [ "$dev_int" -le $((16#1CFF)) ]; then echo true; return; fi
# GP108 — GT 1030, GT 1010, MX150/250/350/330, Quadro P520
if [ "$dev_int" -ge $((16#1D00)) ] && [ "$dev_int" -le $((16#1D7F)) ]; then echo true; return; fi
echo false
}
@@ -77,8 +106,8 @@ is_nvidia_blackwell() {
# Blackwell (GB20x) rango bajo: 0x2900 0x29BF
if [ "$dev_int" -ge $((16#2900)) ] && [ "$dev_int" -le $((16#29BF)) ]; then echo true; return; fi
# Blackwell (GB20x) rango alto: 0x2B80 0x31FF
if [ "$dev_int" -ge $((16#2B80)) ] && [ "$dev_int" -le $((16#31FF)) ]; then echo true; return; fi
# Blackwell (GB20x) rango alto: 0x2B80 0x31DF
if [ "$dev_int" -ge $((16#2B80)) ] && [ "$dev_int" -le $((16#31DF)) ]; then echo true; return; fi
echo false
}
@@ -161,6 +190,7 @@ offer_generic_tools() {
if _confirm "GPU Tools" "Install monitoring and info tools?\n\n${tool_pkgs}"; then
_run_cmd "GPU Tools" "sudo apt install -y nvtop vainfo" "Installing GPU tools..."
vainfo
_pause "vainfo output shown above."
else
echo "Skipping GPU monitoring tools."
fi
+2
View File
@@ -42,6 +42,7 @@ offer_amd_tools() {
_run_cmd "AMD Tools" "sudo apt install -y ${amd_tools[*]} nvtop vainfo" "Installing AMD tools..."
fi
vainfo
_pause "vainfo output shown above."
if $corectrl_available; then
if [ "$DEBIAN_CODENAME" = "trixie" ]; then
@@ -108,6 +109,7 @@ offer_intel_tools() {
if _confirm "Intel Tools" "Intel GPU monitoring tools\n\n${driver_info}\n\nPackages:\n${pkg_info}"; then
_run_cmd "Intel Tools" "sudo apt install -y ${pkg_list[*]} vainfo" "Installing Intel monitoring tools..."
vainfo
_pause "vainfo output shown above."
else
echo "Skipping Intel monitoring tools."
fi
+1
View File
@@ -27,4 +27,5 @@ install_kernel_backports() {
_run_cmd "Kernel" "sudo apt install -y -t ${DEBIAN_CODENAME}-backports linux-image-amd64" "Installing kernel from backports..."
echo -e "${GREEN}Kernel installed. Reboot to use it.${NC}"
_pause
}
+204 -117
View File
@@ -1,5 +1,7 @@
#!/usr/bin/env bash
source "${MODULES_DIR}/repos/migrate.sh" 2>/dev/null || true
# State for backup/restore
REPO_BACKUP_DIR=""
@@ -84,18 +86,19 @@ _clean_embedded_backports_deb822() {
_write_deb822() {
local codename="$1" action="$2" bp_enabled="$3" bp_location="$4"
local components="${5:-main contrib non-free non-free-firmware}"
local main_file="/etc/apt/sources.list.d/debian.sources"
local main_content=""
main_content+="Types: deb\n"
main_content+="URIs: https://deb.debian.org/debian\n"
main_content+="Suites: ${codename} ${codename}-updates\n"
main_content+="Components: main contrib non-free non-free-firmware\n"
main_content+="Components: ${components}\n"
main_content+="\n"
main_content+="Types: deb\n"
main_content+="URIs: https://security.debian.org/debian-security\n"
main_content+="Suites: ${codename}-security\n"
main_content+="Components: main contrib non-free non-free-firmware\n"
main_content+="Components: ${components}\n"
if content_differs "$main_file" "$main_content"; then
if _confirm "Deb822 Sources" "Write main deb822 configuration to ${main_file}?"; then
@@ -174,20 +177,21 @@ _remove_deb822_backports() {
_write_classic() {
local codename="$1" action="$2" bp_enabled="$3" bp_location="$4"
local components="${5:-main contrib non-free non-free-firmware}"
local main_file="/etc/apt/sources.list"
local main_content=""
main_content+="# Official repository\n"
main_content+="deb https://deb.debian.org/debian ${codename} main contrib non-free non-free-firmware\n"
main_content+="# deb-src https://deb.debian.org/debian ${codename} main contrib non-free non-free-firmware\n"
main_content+="deb https://deb.debian.org/debian ${codename} ${components}\n"
main_content+="# deb-src https://deb.debian.org/debian ${codename} ${components}\n"
main_content+="\n"
main_content+="# Updates\n"
main_content+="deb https://deb.debian.org/debian ${codename}-updates main contrib non-free non-free-firmware\n"
main_content+="# deb-src https://deb.debian.org/debian ${codename}-updates main contrib non-free non-free-firmware\n"
main_content+="deb https://deb.debian.org/debian ${codename}-updates ${components}\n"
main_content+="# deb-src https://deb.debian.org/debian ${codename}-updates ${components}\n"
main_content+="\n"
main_content+="# Security\n"
main_content+="deb https://security.debian.org/debian-security ${codename}-security main contrib non-free non-free-firmware\n"
main_content+="# deb-src https://security.debian.org/debian-security ${codename}-security main contrib non-free non-free-firmware\n"
main_content+="deb https://security.debian.org/debian-security ${codename}-security ${components}\n"
main_content+="# deb-src https://security.debian.org/debian-security ${codename}-security ${components}\n"
if content_differs "$main_file" "$main_content"; then
if _confirm "Classic Sources" "Write main classic configuration to ${main_file}?"; then
@@ -273,125 +277,66 @@ configure_repos() {
return 1
fi
# ── Informational banner ──
_msg "Repositories" \
"This section will automatically enable the 'contrib' and \n\
'non-free' branches in your official Debian repositories. \n\
(The 'non-free-firmware' branch is already enabled by default in Debian 12 and 13.)\n\n\
This is CRUCIAL for obtaining proprietary software packages and\n\
essential hardware drivers, including graphics drivers,\n\
Wi-Fi firmware, and CPU microcode." 14 70
# ── Repositories submenu ──
while true; do
local repo_choice
# Detect current state
local current_format
current_format=$(detect_repo_format)
local bp_status
if detect_backports_status "$DEBIAN_CODENAME"; then
bp_status="enabled"
if [ "$DEBIAN_CODENAME" = "sid" ]; then
repo_choice=$(_menu "Repositories" \
"Select an option:" $TUI_ALTO $TUI_ANCHO 6 \
"1" "Enable Contrib & Non-Free Components" \
"2" "Migrate traditional sources.list to DEB822 format" \
"3" "Back to main menu")
else
bp_status="disabled"
fi
local bp_location
bp_location=$(detect_backports_location "$DEBIAN_CODENAME")
echo "Current format: ${current_format:-none}"
echo "Backports: $bp_status (location: $bp_location)"
# ── Format selection dialog (only Trixie gets the choice) ──
local use_deb822=false
if [ "$DEBIAN_CODENAME" = "trixie" ]; then
if whiptail --title "Repository Format" --defaultno --yesno \
"Do you want to migrate your repositories to the new
DEB822 (.sources) format?
DEB822 is the modern, structured Debian standard. It won't
harm your system, and the script will handle the transition
safely if you accept.
NOTE: 'NO' (default) is recommended to maintain the classic
linear format as it comes pre-configured in Debian 13 (Trixie)." 16 70; then
use_deb822=true
fi
elif [ "$current_format" = "deb822" ]; then
use_deb822=true
repo_choice=$(_menu "Repositories" \
"Select an option:" $TUI_ALTO $TUI_ANCHO 6 \
"1" "Enable Contrib & Non-Free Components" \
"2" "Migrate traditional sources.list to DEB822 format" \
"3" "Setup/Update Backports repositories" \
"4" "[ADVANCED] Upgrade system branch (Testing / SID)" \
"5" "Back to main menu")
fi
# Choose backports
local enable_backports=false
if _confirm "Backports" "Do you want to enable the official Debian Backports repository?\n\n\
Backports provides newer, selectively updated packages from the\n\
next Debian testing branch, recompiled to run stably on your\n\
current system.\n\n\
This is HIGHLY RECOMMENDED if you have modern hardware, as it\n\
delivers newer Linux Kernels, updated display drivers, and modern\n\
Mesa versions without compromising overall system stability." 16 70; then
enable_backports=true
fi
[ -z "$repo_choice" ] && break
clear
# Determine what to do
local target_format
$use_deb822 && target_format="deb822" || target_format="classic"
if [ "$current_format" = "none" ]; then
local action="write"
elif [ "$target_format" != "$current_format" ]; then
local action="migrate"
case "$repo_choice" in
1) _repos_enable_components ;;
2) _repos_migrate_format ;;
3)
if [ "$DEBIAN_CODENAME" = "sid" ]; then
break
else
local action="update"
_repos_setup_backports
fi
;;
4) _branch_migration || true ;;
5) break ;;
esac
done
}
# If nothing changed (same format + same backports state), skip
if [ "$action" = "update" ] && [ "$enable_backports" = "$bp_status" ]; then
# Check if backports location is correct (standalone)
if $enable_backports; then
local correct_location="standalone-deb822"
$use_deb822 || correct_location="standalone-classic"
if [ "$bp_location" = "$correct_location" ]; then
# Also verify no embedded backports linger
if [ "$target_format" = "deb822" ]; then
! grep -qE "^Suites:.*${DEBIAN_CODENAME}-backports\b" /etc/apt/sources.list.d/debian.sources 2>/dev/null || { action="update"; true; }
else
! grep -qE "^[^#]*${DEBIAN_CODENAME}-backports\b" /etc/apt/sources.list 2>/dev/null || { action="update"; true; }
fi
if [ "$action" = "update" ]; then
echo "Repository configuration is already up-to-date. Skipping."
return 0
fi
fi
else
# Backports disabled: verify no backports files exist
if [ ! -f /etc/apt/sources.list.d/debian-backports.sources ] && \
[ ! -f /etc/apt/sources.list.d/debian-backports.list ]; then
echo "Repository configuration is already up-to-date. Skipping."
return 0
fi
fi
fi
# ---------------------------------------------------------------------------
# Submenu helpers
# ---------------------------------------------------------------------------
backup_current_repos
if $use_deb822; then
_write_deb822 "$DEBIAN_CODENAME" "$action" "$enable_backports" "$bp_location"
else
_write_classic "$DEBIAN_CODENAME" "$action" "$enable_backports" "$bp_location"
_components_enabled() {
if [ -f /etc/apt/sources.list.d/debian.sources ]; then
for c in $(grep "^Components:" /etc/apt/sources.list.d/debian.sources 2>/dev/null | cut -d: -f2-); do
[ "$c" = "contrib" ] || [ "$c" = "non-free" ] && return 0
done
fi
echo "Updating package lists..."
sudo apt update
local apt_rc=$?
if [ $apt_rc -eq 0 ]; then
REPOS_CONFIGURED=true
echo -e "${GREEN}Repositories configured and updated successfully.${NC}"
if $use_deb822; then
# Remove any leftover disabled files from old classic format
[ -f /etc/apt/sources.list.disabled ] && sudo rm -f /etc/apt/sources.list.disabled
else
[ -f /etc/apt/sources.list.d/debian.sources.disabled ] && sudo rm -f /etc/apt/sources.list.d/debian.sources.disabled
if [ -f /etc/apt/sources.list ]; then
local components
components=$(grep "^[^#]*deb .* main" /etc/apt/sources.list 2>/dev/null | head -1 | sed 's/.*main\s*//')
for c in $components; do
[ "$c" = "contrib" ] || [ "$c" = "non-free" ] && return 0
done
fi
return 1
}
cleanup_repo_backup
_repos_offer_upgrade() {
local upgradable
upgradable=$(apt list --upgradable 2>/dev/null | grep -c /)
if [ "$upgradable" -gt 0 ]; then
@@ -406,9 +351,151 @@ Mesa versions without compromising overall system stability." 16 70; then
echo "Skipping upgrade."
fi
fi
}
_repos_enable_components() {
local current_format bp_enabled bp_location components
current_format=$(detect_repo_format)
if _components_enabled; then
if ! _confirm "Disable Components" \
"Contrib and non-free are already enabled. Disable them?"; then
echo "No changes made."
_pause
return
fi
components="main"
else
if ! _confirm "Enable Components" \
"Enable contrib and non-free components?\n\n\
Needed for proprietary drivers, firmware, and other
popular software (like gaming platforms and proprietary tools)." 12 60; then
echo "No changes made."
_pause
return
fi
components="main contrib non-free non-free-firmware"
fi
bp_enabled=false
bp_location="none"
if detect_backports_status "$DEBIAN_CODENAME"; then
bp_enabled=true
bp_location=$(detect_backports_location "$DEBIAN_CODENAME")
fi
backup_current_repos
if [ "$current_format" = "deb822" ] || [ "$current_format" = "none" ]; then
_write_deb822 "$DEBIAN_CODENAME" "write" "$bp_enabled" "$bp_location" "$components"
else
_write_classic "$DEBIAN_CODENAME" "write" "$bp_enabled" "$bp_location" "$components"
fi
echo "Updating package lists..."
if sudo apt update; then
REPOS_CONFIGURED=true
cleanup_repo_backup
echo -e "${GREEN}Repository components configured.${NC}"
_repos_offer_upgrade
else
restore_previous_repos
echo -e "${RED}apt update failed. Previous repository configuration restored.${NC}"
return 1
echo -e "${RED}apt update failed. Previous configuration restored.${NC}"
fi
_pause
}
_repos_migrate_format() {
local current_format bp_enabled bp_location
current_format=$(detect_repo_format)
if [ "$current_format" != "classic" ]; then
echo "Repositories are already in DEB822 format."
_pause
return
fi
if [ "$DEBIAN_CODENAME" != "trixie" ]; then
echo "Format migration is only relevant for Debian 13 (Trixie)."
_pause
return
fi
# Preserve existing backports state across format migration
bp_enabled=false
bp_location="none"
if detect_backports_status "$DEBIAN_CODENAME"; then
bp_enabled=true
bp_location=$(detect_backports_location "$DEBIAN_CODENAME")
fi
backup_current_repos
_write_deb822 "$DEBIAN_CODENAME" "migrate" "$bp_enabled" "$bp_location"
echo "Updating package lists..."
if sudo apt update; then
REPOS_CONFIGURED=true
cleanup_repo_backup
echo -e "${GREEN}Repository format migrated to DEB822.${NC}"
else
restore_previous_repos
echo -e "${RED}apt update failed. Backup restored.${NC}"
fi
_pause
}
_repos_setup_backports() {
local current_format bp_status bp_location
current_format=$(detect_repo_format)
if detect_backports_status "$DEBIAN_CODENAME"; then
bp_status="enabled"
else
bp_status="disabled"
fi
bp_location=$(detect_backports_location "$DEBIAN_CODENAME")
echo "Backports are currently $bp_status."
local enable_backports=false
if _confirm "Backports" "Do you want to enable the official Debian Backports repository?\n\n\
Backports provides newer, selectively updated packages from the next\n\
Debian testing branch, recompiled to run stably on your current system.\n\n\
Answer NO to disable or remove backports if they are currently enabled." 16 70; then
enable_backports=true
fi
# Nothing to do — already in desired state
if { $enable_backports && [ "$bp_status" = "enabled" ]; } || \
{ ! $enable_backports && [ "$bp_status" = "disabled" ]; }; then
echo "Backports are already configured as requested."
_pause
return
fi
backup_current_repos
if $enable_backports; then
if [ "$current_format" = "deb822" ]; then
_write_deb822_backports "$DEBIAN_CODENAME"
else
_write_classic_backports "$DEBIAN_CODENAME"
fi
else
if [ "$current_format" = "deb822" ]; then
_remove_deb822_backports "$DEBIAN_CODENAME"
else
_remove_classic_backports "$DEBIAN_CODENAME"
fi
fi
echo "Updating package lists..."
if sudo apt update; then
cleanup_repo_backup
echo -e "${GREEN}Backports configured.${NC}"
else
restore_previous_repos
echo -e "${RED}apt update failed. Backup restored.${NC}"
fi
_pause
}
+176
View File
@@ -0,0 +1,176 @@
#!/usr/bin/env bash
# migrate.sh — Stable → Testing / SID branch migration
# License GPL v3
_MIGRATE_BACKUP=""
_persistent_backup_repos() {
local stamp
stamp=$(date +%Y%m%d-%H%M%S)
_MIGRATE_BACKUP="/var/backups/debianito-repos-${stamp}.tar.gz"
sudo mkdir -p /var/backups
local files=()
[ -f /etc/apt/sources.list ] && files+=("/etc/apt/sources.list")
[ -d /etc/apt/sources.list.d ] && files+=("/etc/apt/sources.list.d")
[ ${#files[@]} -eq 0 ] && return 1
sudo tar czf "$_MIGRATE_BACKUP" "${files[@]}" 2>/dev/null
echo "Backup: $_MIGRATE_BACKUP"
}
_restore_backup() {
if [ -z "$_MIGRATE_BACKUP" ] || [ ! -f "$_MIGRATE_BACKUP" ]; then
_msg "Restore Error" "No backup found at $_MIGRATE_BACKUP.\nCannot restore. Your system may be in an inconsistent state." 10 70
return 1
fi
echo -e "${YELLOW}Restoring repository backup...${NC}"
sudo tar xzf "$_MIGRATE_BACKUP" -C / 2>/dev/null
echo -e "${GREEN}Backup restored from $_MIGRATE_BACKUP${NC}"
}
_write_deb822_branch() {
local target="$1"
local main_file="/etc/apt/sources.list.d/debian.sources"
local main_content=""
if [ "$target" = "sid" ]; then
main_content+="Types: deb\n"
main_content+="URIs: https://deb.debian.org/debian\n"
main_content+="Suites: sid\n"
main_content+="Components: main contrib non-free non-free-firmware\n"
main_content+="\n"
main_content+="Types: deb\n"
main_content+="URIs: https://security.debian.org/debian-security\n"
main_content+="Suites: sid\n"
main_content+="Components: main contrib non-free non-free-firmware\n"
else
# testing
main_content+="Types: deb\n"
main_content+="URIs: https://deb.debian.org/debian\n"
main_content+="Suites: testing testing-updates\n"
main_content+="Components: main contrib non-free non-free-firmware\n"
main_content+="\n"
main_content+="Types: deb\n"
main_content+="URIs: https://security.debian.org/debian-security\n"
main_content+="Suites: testing-security\n"
main_content+="Components: main contrib non-free non-free-firmware\n"
fi
sudo mkdir -p /etc/apt/sources.list.d
echo -e "$main_content" | sudo tee "$main_file" > /dev/null
echo "Wrote $main_file"
}
_branch_migration() {
# ── Screen 1: Risk warning ──
_msg_red "WARNING: Branch Migration" \
"Migrating from Debian Stable to Testing or SID is a\n\
MAJOR change and CAN make your system UNBOOTABLE.\n\n\
Risks include:\n\
• NVIDIA / DKMS drivers may break\n\
• System may fail to boot after reboot\n\
• Some packages may be removed or replaced\n\
• SID (unstable) receives NO security updates\n\n\
A full persistent backup will be saved to /var/backups/\n\
so you can restore if things go wrong." 16 70
if ! _confirm "Branch Migration" "Do you want to proceed with the migration?"; then
echo "Migration cancelled."
return
fi
# ── Screen 2: Plan summary ──
local plan="This operation will:\n\n"
plan+=" 1. Backup current APT sources to /var/backups/\n"
plan+=" 2. Remove any backports configuration\n"
plan+=" 3. Write new DEB822 sources for the target branch\n"
plan+=" 4. Run: apt update\n"
plan+=" 5. Run: apt upgrade -y\n"
plan+=" 6. Run: apt full-upgrade -y\n"
plan+=" 7. Run: apt autoremove -y\n\n"
plan+="If apt update fails, the backup is restored immediately."
_msg_red "Migration Plan" "$plan" 16 70
if ! _confirm "Migration Plan" "Proceed with the plan?"; then
echo "Migration cancelled."
return
fi
# ── Screen 3: Branch selection ──
local branch
branch=$(_inputbox "Target Branch" \
"Type exactly TESTING or SID (case-sensitive):" 10 60 "")
[ -z "$branch" ] && { echo "Migration cancelled."; return; }
if [ "$branch" != "TESTING" ] && [ "$branch" != "SID" ]; then
_msg "Invalid Branch" "You typed: $branch\n\nExpected: TESTING or SID (exact, case-sensitive).\nAborting." 10 60
return
fi
# Normalize to lowercase for internal use
local target
target=$(echo "$branch" | tr '[:upper:]' '[:lower:]')
# ── Screen 4: Execution ──
echo -e "${YELLOW}Starting branch migration to ${target}...${NC}"
# 4a. Persistent backup
echo "Creating backup..."
_persistent_backup_repos || {
_msg "Backup Error" "Failed to create backup. Aborting." 8 60
return
}
# 4b. Clean backports
echo "Removing backports configuration..."
[ -f /etc/apt/sources.list.d/debian-backports.sources ] && sudo rm -f /etc/apt/sources.list.d/debian-backports.sources
[ -f /etc/apt/sources.list.d/debian-backports.list ] && sudo rm -f /etc/apt/sources.list.d/debian-backports.list
# 4c. Remove any old classic source files to avoid conflicts
[ -f /etc/apt/sources.list ] && sudo rm -f /etc/apt/sources.list
# 4d. Write new sources
_write_deb822_branch "$target"
# 4e. SID guardrails: install bug alerts before upgrade
if [ "$target" = "sid" ]; then
echo -e "${YELLOW}Installing apt-listbugs and apt-listchanges (SID guardrails)...${NC}"
sudo apt update -qq 2>/dev/null || true
sudo DEBIAN_FRONTEND=noninteractive apt install -y apt-listbugs apt-listchanges || true
fi
# 4f. apt update with rollback on failure
echo -e "${YELLOW}Running apt update...${NC}"
if ! sudo apt update; then
echo -e "${RED}apt update failed. Restoring backup...${NC}"
_restore_backup
_msg_red "Migration Failed" \
"apt update failed. Backup has been restored from:\n\
$_MIGRATE_BACKUP\n\n\
Your system should be back to its previous state.\n\
Run 'sudo apt update' manually to verify." 12 70
return
fi
# 4g. Full upgrade
_run_cmd "Upgrade" "sudo apt upgrade -y" "Upgrading packages..."
_run_cmd "Full-Upgrade" "sudo apt full-upgrade -y" "Running full-upgrade..."
_run_cmd "Autoremove" "sudo apt autoremove -y" "Removing obsolete packages..."
# 4h. Re-run detection to reflect new branch
echo -e "${YELLOW}Re-running system detection for new branch...${NC}"
detect_debian_version
detect_kernel
detect_gpu
detect_storage
echo -e "${GREEN}Branch migration to ${target} completed successfully.${NC}"
# ── Screen 5: Reboot reminder ──
_msg "Migration Complete" \
"System has been migrated to ${target}.\n\n\
Backup saved at:\n $_MIGRATE_BACKUP\n\n\
REBOOT your system.\nIf it fails to boot, restore the backup manually:\n\
sudo tar xzf $_MIGRATE_BACKUP -C /\n sudo apt update\n sudo apt upgrade" 16 70
}
+188
View File
@@ -0,0 +1,188 @@
#!/usr/bin/env bash
# rescue.sh — UEFI boot repair and system rescue utilities
_rescue_boot_sb() {
echo -e "${YELLOW}UEFI Secure Boot repair...${NC}"
if [ ! -d /sys/firmware/efi ]; then
echo -e "${RED}Not a UEFI system. Skipping.${NC}"
_pause
return
fi
local sb_state
sb_state=$(mokutil --sb-state 2>/dev/null)
if ! echo "$sb_state" | grep -qi "enabled"; then
echo -e "${YELLOW}Secure Boot is not enabled. No refirm needed.${NC}"
_pause
return
fi
if ! _confirm "Secure Boot Repair" \
"Secure Boot is enabled.\n\nReinstall and refirm shim-signed + GRUB?\n\nThis fixes boot issues where Debian is skipped\nin UEFI after kernel/driver changes."; then
echo "Skipped."
_pause
return
fi
local efi_dir="/boot/efi"
[ ! -d "$efi_dir" ] && efi_dir="/boot"
_run_cmd "Refirm" \
"sudo apt install --reinstall -y shim-signed grub-efi-amd64-signed linux-image-amd64" \
"Reinstalling signed boot packages..."
_run_cmd "GRUB Install" \
"sudo grub-install --target=x86_64-efi --efi-directory=$efi_dir --bootloader-id=debian --recheck" \
"Reinstalling GRUB to EFI partition..."
_run_cmd "GRUB Config" \
"sudo update-grub" \
"Regenerating GRUB configuration..."
echo -e "${GREEN}Boot repair complete. Reboot to verify.${NC}"
_pause
}
_rescue_initramfs() {
if ! _confirm "Initramfs" "Regenerate initramfs for all kernels?\n\nFixes boot issues caused by missing drivers\nor corrupted initrd images."; then
echo "Skipped."
_pause
return
fi
_run_cmd "Initramfs" "sudo update-initramfs -u -k all" "Regenerating initramfs for all kernels..."
echo -e "${GREEN}Initramfs regenerated.${NC}"
_pause
}
# ----------------------------------------------------------------------
# GRUB helpers
# ----------------------------------------------------------------------
_set_grub_var() {
local var="$1" val="$2" file="/etc/default/grub"
if grep -q "^${var}=" "$file" 2>/dev/null; then
sudo sed -i "s/^${var}=.*/${var}=${val}/" "$file"
elif grep -q "^#${var}=" "$file" 2>/dev/null; then
sudo sed -i "s/^#${var}=.*/${var}=${val}/" "$file"
else
echo "${var}=${val}" | sudo tee -a "$file" >/dev/null
fi
}
_apply_grub_setting() {
local timeout="$1" style="$2" recordfail="$3" os_prober="$4"
local file="/etc/default/grub"
local backup="${file}.backup.$(date +%Y%m%d_%H%M%S)"
local override="/etc/default/grub.d/99_script_override.cfg"
sudo cp "$file" "$backup"
_set_grub_var GRUB_TIMEOUT "$timeout"
_set_grub_var GRUB_TIMEOUT_STYLE "$style"
_set_grub_var GRUB_RECORDFAIL_TIMEOUT "$recordfail"
[ -n "$os_prober" ] && _set_grub_var GRUB_DISABLE_OS_PROBER "$os_prober"
sudo mkdir -p /etc/default/grub.d
if [ -n "$os_prober" ]; then
cat << EOF | sudo tee "$override" > /dev/null
GRUB_TIMEOUT_STYLE=$style
GRUB_TIMEOUT=$timeout
GRUB_RECORDFAIL_TIMEOUT=$recordfail
GRUB_DISABLE_OS_PROBER=$os_prober
EOF
else
cat << EOF | sudo tee "$override" > /dev/null
GRUB_TIMEOUT=$timeout
GRUB_TIMEOUT_STYLE=$style
GRUB_RECORDFAIL_TIMEOUT=$recordfail
EOF
fi
local summary
summary="Settings applied:\n\n"
summary+=" GRUB_TIMEOUT=$timeout\n"
summary+=" GRUB_TIMEOUT_STYLE=$style\n"
summary+=" GRUB_RECORDFAIL_TIMEOUT=$recordfail\n"
[ -n "$os_prober" ] && summary+=" GRUB_DISABLE_OS_PROBER=$os_prober\n"
summary+="\nRunning update-grub..."
echo -e "$summary"
if sudo update-grub >/dev/null 2>&1; then
_msg "GRUB Settings" \
"GRUB settings applied successfully!\n\nBackup saved: ${backup}\n\nReboot to see the changes."
else
echo -e "${RED}update-grub failed. Restoring backup...${NC}"
sudo cp "$backup" "$file"
sudo rm -f "$override"
_msg "Error" "update-grub failed.\nBackup restored from ${backup}\nOverride removed: ${override}."
fi
}
_grub_menu_settings() {
while true; do
local choice
choice=$(_menu "GRUB Boot Menu Settings" \
"Configure when and how the GRUB menu appears${SCROLL_HINT}:" \
$TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
"1" "Disable GRUB menu on start (Fastest boot)" \
"2" "Faster boot (Show 3-sec countdown)" \
"3" "Default boot (Show menu for 5 secs)" \
"4" "Custom timeout (Input seconds)" \
"5" "Back")
[ -z "$choice" ] && return
clear
case "$choice" in
1)
if _confirm "Disable GRUB Menu" \
"GRUB menu will be hidden entirely for fastest boot.\n\nTo access the menu on next boot, press and hold ESC\nimmediately after powering on.\n\nProceed?"; then
_apply_grub_setting 0 hidden 0 true
fi
;;
2)
_apply_grub_setting 3 menu 3 ""
;;
3)
_apply_grub_setting 5 menu 5 ""
;;
4)
local custom_timeout
custom_timeout=$(whiptail --title "Custom GRUB Timeout" \
--inputbox "Enter the GRUB timeout in seconds.\n\nUse -1 for indefinite wait." \
10 60 "" 3>&1 1>&2 2>&3 || true)
if [ -n "$custom_timeout" ]; then
if [[ "$custom_timeout" =~ ^-?[0-9]+$ ]]; then
_apply_grub_setting "$custom_timeout" menu "$custom_timeout" ""
else
_msg "Invalid Input" "Please enter a valid integer (e.g. 0, 5, -1)."
fi
fi
;;
5) return ;;
esac
done
}
rescue_boot() {
while true; do
local choice
choice=$(_menu "Boot Rescue + GRUB Configuration" \
"Select an operation${SCROLL_HINT}:" \
$TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
"1" "GRUB Boot Menu Settings" \
"2" "Refirm Secure Boot (shim + GRUB)" \
"3" "Regenerate initramfs (all kernels)" \
"4" "Return to main menu")
[ -z "$choice" ] && return
clear
case "$choice" in
1) _grub_menu_settings ;;
2) _rescue_boot_sb ;;
3) _rescue_initramfs ;;
4) return ;;
esac
done
}
+7 -12
View File
@@ -7,14 +7,13 @@ config_sudo() {
while true; do
local choice
choice=$(whiptail --title "User Privileges & Feedback" --menu \
choice=$(_menu "User Privileges & Feedback" \
"Select an option:" $TUI_ALTO $TUI_ANCHO 6 \
"1" "Sudo Group Membership" \
"2" "Passwordless Sudo (maintenance commands)" \
"3" "Repair Home Directory Ownership" \
"4" "Sudo Password Feedback (asterisks)" \
"5" "Back to main menu" \
3>&1 1>&2 2>&3)
"5" "Back to main menu")
[ -z "$choice" ] && return
clear
@@ -67,12 +66,11 @@ _configure_nopasswd() {
- shutdown / reboot / halt (power commands)\n\n\
Useful for automation but reduces security." 14 70; then
local choices
choices=$(whiptail --title "NOPASSWD Commands" --checklist \
choices=$(_checklist "NOPASSWD Commands" \
"Select commands to allow without password:" 12 60 3 \
"apt" "APT package management" ON \
"systemctl" "Systemd service management" ON \
"power" "Shutdown, reboot, halt" ON \
3>&1 1>&2 2>&3)
"power" "Shutdown, reboot, halt" ON)
clear
[ -z "$choices" ] && { echo "No commands selected."; return; }
@@ -93,12 +91,10 @@ Useful for automation but reduces security." 14 70; then
esac
done
echo -e "$content" | sudo tee "$nopasswd_file" > /dev/null
sudo chmod 0440 "$nopasswd_file"
if [ -f "$nopasswd_file" ]; then
local content_str; content_str=$(echo -e "$content")
if _validate_sudoers "$content_str" "$nopasswd_file"; then
echo -e "${GREEN}Passwordless sudo configured for selected commands.${NC}"
else
echo -e "${RED}Failed to configure passwordless sudo.${NC}"
return 1
fi
fi
@@ -148,10 +144,9 @@ _toggle_pwfeedback() {
else
if _confirm "Password Feedback" \
"Show asterisks when typing the sudo password?"; then
if echo 'Defaults pwfeedback' | sudo tee "$fb_file" > /dev/null 2>&1; then
if _validate_sudoers 'Defaults pwfeedback' "$fb_file"; then
echo -e "${GREEN}Password feedback enabled.${NC}"
else
echo -e "${RED}Failed to create $fb_file${NC}"
return 1
fi
fi
+185
View File
@@ -0,0 +1,185 @@
#!/usr/bin/env bash
# swap.sh — Disk-based swap management (swapfile + swappiness)
# Independent of zram.sh. Uses pri=10 to coexist with ZRAM priority=100.
readonly SWAP_FILE="/swapfile"
readonly SWAP_FSTAB_TAG="# debianito-managed-swap"
readonly SWAP_PRIORITY="10"
readonly SWAP_CONF="/etc/sysctl.d/99-swappiness-debianito.conf"
readonly SWAP_LOCK="/run/lock/debianito-swap.lock"
# ── Helpers ──
_swap_valid_fstab() {
local tmp="$1"
sudo findmnt --verify --fstab "$tmp" >/dev/null 2>&1
}
_swap_safe_write_fstab() {
local line="$1"
local tmp
tmp=$(mktemp) || return 1
sudo cp /etc/fstab "$tmp"
sudo sed -i "/$SWAP_FSTAB_TAG/d" "$tmp"
[ -n "$line" ] && printf '%s\n' "$line" >> "$tmp"
if _swap_valid_fstab "$tmp"; then
sudo install -o root -g root -m 0644 "$tmp" /etc/fstab
else
local err
err=$(sudo findmnt --verify --fstab "$tmp" 2>&1 || true)
rm -f "$tmp"
_msg "fstab Error" "Validation failed — changes NOT applied.\n\n$err" 12 70
return 1
fi
rm -f "$tmp"
}
_swap_recommend_gb() {
if [ -z "${RAM_GB:-}" ]; then
echo 2
return
fi
local ram
ram=$(echo "$RAM_GB" | awk '{print int($1)}')
if [ "$ram" -ge 16 ]; then
echo 2
elif [ "$ram" -ge 8 ]; then
echo 4
else
local rec
rec=$((ram * 2))
[ "$rec" -lt 1 ] && rec=1
echo "$rec"
fi
}
# ── Menu options ──
_swap_current_status() {
local info="── Current swap ──\n"
info+="$(sudo swapon --show 2>/dev/null || echo '(none active)')\n\n"
info+="swappiness: $(cat /proc/sys/vm/swappiness)\n\n"
info+="fstab swap entries:\n"
info+="$(grep -E 'swap|SWAP' /etc/fstab 2>/dev/null || echo '(none in fstab)')"
_msg "Swap Status" "$info" 14 65
}
_swap_create_file() {
local fstype rec_gb
fstype=$(stat -f -c %T "$(dirname "$SWAP_FILE")" 2>/dev/null || echo "ext4")
rec_gb=$(_swap_recommend_gb)
local warn=""
if [ "$fstype" = "btrfs" ]; then
warn="Filesystem: Btrfs\nSwapfile on Btrfs needs extra steps (nodatacow).\nHibernation requires swap ≥ RAM and manual resume= config.\n\n"
fi
warn+="ZRAM (priority 100) is used first.\nDisk swap (priority $SWAP_PRIORITY) is only consumed after ZRAM fills."
_msg "Swapfile Info" "$warn" 14 65
local size_gb
size_gb=$(_inputbox "Swapfile Size" "Size in GB for $SWAP_FILE:" 10 60 "$rec_gb")
[ -z "$size_gb" ] && return
[[ "$size_gb" =~ ^[0-9]+$ ]] && [ "$size_gb" -gt 0 ] || {
_msg "Error" "Enter a positive integer." 8 40
return
}
if [ -f "$SWAP_FILE" ]; then
_confirm "Swapfile exists" "$SWAP_FILE already exists.\nRecreate it (${size_gb} GB)?" || return
sudo swapoff "$SWAP_FILE" 2>/dev/null || true
sudo rm -f "$SWAP_FILE"
fi
echo -e "${YELLOW}Allocating ${size_gb}G swapfile...${NC}"
if [ "$fstype" = "btrfs" ]; then
sudo touch "$SWAP_FILE"
sudo chattr +C "$SWAP_FILE" 2>/dev/null || true
sudo dd if=/dev/zero of="$SWAP_FILE" bs=1M count=$((size_gb * 1024)) status=progress
else
sudo fallocate -l "${size_gb}G" "$SWAP_FILE" || \
sudo dd if=/dev/zero of="$SWAP_FILE" bs=1M count=$((size_gb * 1024)) status=progress
fi
sudo chmod 600 "$SWAP_FILE"
sudo mkswap "$SWAP_FILE" >/dev/null
sudo swapon "$SWAP_FILE"
local fstab_line
fstab_line="$SWAP_FILE none swap sw,pri=$SWAP_PRIORITY 0 0 $SWAP_FSTAB_TAG # pri=$SWAP_PRIORITY (below zram 100)"
if _swap_safe_write_fstab "$fstab_line"; then
_msg "Swapfile" "Swapfile created and added to fstab (persistent).\n\nPriority: $SWAP_PRIORITY (below ZRAM 100)." 12 65
else
sudo swapoff "$SWAP_FILE" 2>/dev/null || true
sudo rm -f "$SWAP_FILE"
fi
}
_swap_remove_file() {
local has_tag
has_tag=$(grep -c "$SWAP_FSTAB_TAG" /etc/fstab 2>/dev/null || echo 0)
[ "$has_tag" -eq 0 ] && [ ! -f "$SWAP_FILE" ] && {
_msg "Swap" "No managed swapfile found." 8 50
return
}
_confirm "Remove Swapfile" "Disable and delete $SWAP_FILE?\n\nRemoves fstab entry and deletes the file." || return
sudo swapoff "$SWAP_FILE" 2>/dev/null || true
_swap_safe_write_fstab ""
sudo rm -f "$SWAP_FILE"
_msg "Swap" "Swapfile removed and fstab entry cleaned." 8 60
}
_swap_set_swappiness() {
local cur val
cur=$(cat /proc/sys/vm/swappiness 2>/dev/null || echo 60)
val=$(_inputbox "Swappiness" "Current value: $cur\nEnter new value (0-100):" 10 60 "$cur")
[ -z "$val" ] && return
[[ "$val" =~ ^[0-9]+$ ]] && [ "$val" -le 100 ] || {
_msg "Error" "Value must be 0-100." 8 40
return
}
local tmp
tmp=$(mktemp) || return
printf 'vm.swappiness=%s\n' "$val" > "$tmp"
sudo install -o root -g root -m 0644 "$tmp" "$SWAP_CONF"
sudo sysctl -w "vm.swappiness=$val" >/dev/null
rm -f "$tmp"
_msg "Swappiness" "swappiness set to $val (persistent)." 8 60
}
# ── Entry point ──
manage_swap() {
exec 9>"$SWAP_LOCK"
flock -n 9 || {
_msg "Busy" "Another swap operation is already running." 8 55
return
}
while true; do
local choice
choice=$(_menu "Swap Management (disk)" \
"Select an option:" $TUI_ALTO $TUI_ANCHO 6 \
"1" "Show current swap & swappiness" \
"2" "Create / resize swapfile" \
"3" "Remove swapfile" \
"4" "Change swappiness" \
"5" "Back to main menu")
[ -z "$choice" ] && break
clear
case "$choice" in
1) _swap_current_status ;;
2) _swap_create_file ;;
3) _swap_remove_file ;;
4) _swap_set_swappiness ;;
5) break ;;
esac
done
exec 9>&-
}
+139 -34
View File
@@ -45,53 +45,158 @@ _show_sysinfo() {
fi
msg+="\n"
# ── Network Block ──
# ── Network Block (PCI class + live interfaces) ──
msg+="─── Network ───\n"
local has_network=false
local i
# ── 1. Detect ALL Ethernet chipsets (class 0x0200) ──
declare -a pci_eth_lines=()
while IFS= read -r line; do
pci_eth_lines+=("$line")
done < <(lspci -d ::0200 2>/dev/null || true)
# ── 2. Detect ALL WiFi chipsets (class 0x0280 + vendor fallbacks) ──
declare -a pci_wifi_lines=()
while IFS= read -r line; do
pci_wifi_lines+=("$line")
done < <(lspci -d ::0280 2>/dev/null || true)
# Broadcom vendor-ID fallback (14e4) — include only if not already captured
while IFS= read -r line; do
if echo "$line" | grep -qi '14e4:'; then
local already=false
for existing in "${pci_wifi_lines[@]}"; do
[ "$existing" = "$line" ] && already=true && break
done
! $already && pci_wifi_lines+=("$line")
fi
done < <(lspci -nn 2>/dev/null || true)
# USB WiFi fallback
local usb_wifi_lines=()
while IFS= read -r line; do
usb_wifi_lines+=("$line")
done < <(lsusb 2>/dev/null | grep -iE 'wireless|wifi|wlan|802\.11' || true)
# ── 3. Build chipset description arrays ──
local -a eth_descs=()
local -a wifi_descs=()
local line desc
for line in "${pci_eth_lines[@]}"; do
desc=$(echo "$line" | sed -E 's/^.*\]: //; s/ \[[0-9a-fA-F]{4}:[0-9a-fA-F]{4}\]//; s/ \(rev [0-9a-fA-F]+\)//')
eth_descs+=("$desc")
done
for line in "${pci_wifi_lines[@]}"; do
desc=$(echo "$line" | sed -E 's/^.*\]: //; s/ \[[0-9a-fA-F]{4}:[0-9a-fA-F]{4}\]//; s/ \(rev [0-9a-fA-F]+\)//')
wifi_descs+=("$desc")
done
for line in "${usb_wifi_lines[@]}"; do
desc=$(echo "$line" | sed 's/^.*ID //')
wifi_descs+=("$desc")
done
# ── 4. Enumerate live interfaces ──
local -a shown_eth_descs=()
local -a shown_wifi_descs=()
local has_eth=false has_wifi=false has_other=false
if ! command -v ip &>/dev/null; then
msg+="(install iproute2 for interface details)\n"
else
for i in "${!ETH_NAMES[@]}"; do
has_network=true
local e_iface="${ETH_NAMES[$i]}"
local e_desc="${ETH_DESCS[$i]:-$ETH_DESC}"
local e_state="${ETH_STATES[$i]}"
local e_ip4="${ETH_IPS[$i]}"
if [ "$e_state" = "UP" ]; then
msg+="${e_iface}: ${e_desc}\n ↑ ${e_ip4:-no IP}\n"
else
msg+="${e_iface}: ${e_desc}\n ↓\n"
fi
done
while IFS= read -r line; do
local iface state ip4 ssid
iface=$(echo "$line" | awk -F': ' '{print $2}' | sed 's/@.*//')
state=$(echo "$line" | awk '{print $9}')
local found_active_wifi=false
for i in "${!WIFI_NAMES[@]}"; do
found_active_wifi=true
has_network=true
local w_iface="${WIFI_NAMES[$i]}"
local w_desc="${WIFI_DESCS[$i]:-$WIFI_DESC}"
local w_state="${WIFI_STATES[$i]}"
local w_ip4="${WIFI_IPS[$i]}"
local w_ssid="${WIFI_SSIDS[$i]}"
if [ "$w_state" = "UP" ]; then
msg+="${w_iface}: ${w_desc}\n ↑ ${w_ip4:-no IP}"
[ -n "$w_ssid" ] && msg+=" \"${w_ssid}\""
case "$iface" in
lo|docker*|veth*|br-*|virbr*|tun*|tap*|bond*) continue ;;
esac
ip4=$(ip -4 -o addr show "$iface" 2>/dev/null | awk '{print $4}')
# Determine type by PCI class (most reliable)
local pci_class=""
pci_class=$(cat "/sys/class/net/${iface}/device/class" 2>/dev/null || true)
case "$pci_class" in
0x0200*)
has_eth=true
desc="${eth_descs[0]:-Unknown Ethernet chipset}"
shown_eth_descs+=("${eth_descs[0]}")
;;
0x0280*)
has_wifi=true
desc="${wifi_descs[0]:-Unknown WiFi chipset}"
shown_wifi_descs+=("${wifi_descs[0]}")
ssid=""
[ "$state" = "UP" ] && ssid=$(iwgetid -r "$iface" 2>/dev/null || true)
;;
*)
# Fallback: classify by interface name pattern
case "$iface" in
wl*|wlp*|wlo*|wlan*)
has_wifi=true
desc="${wifi_descs[0]:-Unknown WiFi chipset}"
shown_wifi_descs+=("${wifi_descs[0]}")
ssid=""
[ "$state" = "UP" ] && ssid=$(iwgetid -r "$iface" 2>/dev/null || true)
;;
eth*|enp*|ens*|enx*|eno*)
has_eth=true
desc="${eth_descs[0]:-Unknown Ethernet chipset}"
shown_eth_descs+=("${eth_descs[0]}")
;;
*)
has_other=true
desc="(network interface)"
;;
esac
;;
esac
if [ "$state" = "UP" ]; then
msg+="${iface}: ${desc}\n ↑ ${ip4:-no IP}"
if [ "$pci_class" = "0x0280" ] || [[ "$iface" == wl* ]]; then
[ -n "${ssid:-}" ] && msg+=" \"${ssid}\""
fi
msg+="\n"
else
msg+="${w_iface}: ${w_desc}\n ↓\n"
msg+="${iface}: ${desc}\n ↓\n"
fi
done < <(ip -o link show 2>/dev/null)
fi
# ── 5. Show chipsets without an active interface ──
local chip
for chip in "${eth_descs[@]}"; do
local found=false
for shown in "${shown_eth_descs[@]}"; do
[ "$chip" = "$shown" ] && found=true && break
done
if ! $found; then
msg+="Ethernet: ${chip}\n (no active interface)\n"
shown_eth_descs+=("$chip")
fi
done
if ! $found_active_wifi && [ -n "$WIFI_DESC" ]; then
has_network=true
msg+="WiFi: ${WIFI_DESC}\n"
msg+=" (no driver — install firmware)\n"
for chip in "${wifi_descs[@]}"; do
local found=false
for shown in "${shown_wifi_descs[@]}"; do
[ "$chip" = "$shown" ] && found=true && break
done
if ! $found; then
msg+="WiFi: ${chip}\n (no active interface)\n"
shown_wifi_descs+=("$chip")
fi
done
if ! $has_network; then
msg+="No active interfaces detected\n"
# ── 6. Nothing at all ──
if ! $has_eth && ! $has_wifi && ! $has_other && [ ${#eth_descs[@]} -eq 0 ] && [ ${#wifi_descs[@]} -eq 0 ]; then
if command -v ip &>/dev/null; then
msg+="No network interfaces detected\n"
else
msg+="(install iproute2 for interface details)\n"
fi
fi
+195 -37
View File
@@ -43,12 +43,12 @@ check_sudo() {
# Time sync detection + NTP
# --------------------------------
check_system_time() {
if ! command -v timedatectl &> /dev/null; then
return
fi
command -v timedatectl &>/dev/null || return
local year
year=$(date +%Y)
if [ "$year" -lt 2026 ]; then
if [ "$year" -lt 2025 ]; then
local msg="System date/time appears to be incorrect\n"
msg+="($(date '+%Y-%m-%d %H:%M')). This will prevent Debian\n"
msg+="repositories from working properly.\n\n"
@@ -56,31 +56,40 @@ check_system_time() {
msg+="(requires network access and timedatectl)"
if _confirm "System Date" "$msg"; then
sync_system_time
local new_year
new_year=$(date +%Y)
if [ "$new_year" -ge 2026 ]; then
echo -e "${GREEN}Time synced: $(date '+%Y-%m-%d %H:%M')${NC}"
else
echo -e "${RED}Could not sync time automatically.${NC}"
echo "You may need to set it manually: sudo date --set \"YYYY-MM-DD HH:MM:SS\""
fi
else
echo -e "${YELLOW}Warning: System time is incorrect. Package installations may fail.${NC}"
fi
return
fi
local ntp_active
ntp_active=$(timedatectl show --property=NTP --value 2>/dev/null || echo "no")
if [ "$ntp_active" != "yes" ]; then
sync_system_time
fi
}
sync_system_time() {
if command -v timedatectl &> /dev/null; then
local ntp_active
ntp_active=$(timedatectl show --property=NTP --value 2>/dev/null || echo "no")
if [ "$ntp_active" != "yes" ]; then
echo -e "${YELLOW}NTP not active. Attempting to enable time sync...${NC}"
sudo timedatectl set-ntp true 2>/dev/null || true
sleep 4
command -v timedatectl &>/dev/null || return
if ! is_installed systemd-timesyncd; then
sudo DEBIAN_FRONTEND=noninteractive apt install -y systemd-timesyncd || true
fi
elif command -v hwclock &> /dev/null && command -v ntpd &> /dev/null; then
sudo hwclock --hctosys 2>/dev/null || true
if ! systemctl is-enabled systemd-timesyncd &>/dev/null; then
sudo systemctl enable systemd-timesyncd || true
fi
if ! systemctl is-active systemd-timesyncd &>/dev/null; then
sudo systemctl start systemd-timesyncd || true
fi
sudo timedatectl set-ntp true || true
sleep 4
if timedatectl show --property=NTPSynchronized --value 2>/dev/null | grep -q yes; then
echo -e "${GREEN}Time synchronized: $(date '+%Y-%m-%d %H:%M')${NC}"
else
echo -e "${YELLOW}NTP sync did not complete.${NC}"
fi
}
@@ -93,9 +102,8 @@ detect_debian_version() {
DEBIAN_CODENAME=$(grep -oP 'VERSION_CODENAME=\K\w+' /etc/os-release 2>/dev/null || echo "")
fi
if [ -z "$DEBIAN_CODENAME" ]; then
echo -e "${YELLOW}Installing lsb-release...${NC}"
sync_system_time
sudo apt update -qq 2>/dev/null && sudo apt install -y -qq lsb-release
sync_system_time || true
sudo apt update -qq 2>/dev/null && sudo apt install -y -qq lsb-release || true
fi
fi
if [ -z "$DEBIAN_CODENAME" ]; then
@@ -150,6 +158,10 @@ is_installed() {
dpkg -l "$1" 2>/dev/null | grep -q '^ii'
}
_state() {
is_installed "$1" && echo "ON" || echo "OFF"
}
# ----------------------------------
# Package version lookup
# ----------------------------------
@@ -275,11 +287,29 @@ detect_network() {
fi
local wifi_line
wifi_line=$(lspci -nn | grep -i 'Network controller' | head -n1) || true
# Layer 1: grep by PCI class description text
wifi_line=$(lspci -nn 2>/dev/null | grep -iE 'network controller|wireless|wi-fi|wlan|802\.11' | head -n1) || true
# Layer 2: grep by exact PCI class code 0x0280 (Network controller)
if [ -z "$wifi_line" ]; then
wifi_line=$(lspci -d ::0280 2>/dev/null | head -n1) || true
fi
# Layer 3: Broadcom vendor ID fallback (14e4)
if [ -z "$wifi_line" ]; then
wifi_line=$(lspci -nn 2>/dev/null | grep -i '14e4:' | head -n1) || true
fi
if [ -n "$wifi_line" ]; then
WIFI_CHIPSET="$wifi_line"
WIFI_DESC=$(echo "$wifi_line" | sed -E 's/^.*\]: //; s/ \[[0-9a-fA-F]{4}:[0-9a-fA-F]{4}\]//; s/ \(rev [0-9a-fA-F]+\)//')
fi
# Layer 4: USB WiFi adapter (no PCI device)
if [ -z "$wifi_line" ] && command -v lsusb &>/dev/null; then
local usb_wifi
usb_wifi=$(lsusb 2>/dev/null | grep -iE 'wireless|wifi|wlan|802\.11' | head -n1) || true
if [ -n "$usb_wifi" ]; then
WIFI_CHIPSET="$usb_wifi"
WIFI_DESC=$(echo "$usb_wifi" | sed 's/^.*ID //')
fi
fi
# ── Safeguard: if ip is not installed, skip runtime parsing ──
if ! command -v ip &>/dev/null; then
@@ -299,7 +329,7 @@ detect_network() {
ETH_IPS+=("${ip4:-}")
ETH_DESCS+=("${ETH_DESC:-}")
;;
wl*|wlp*|wlo*)
wl*|wlp*|wlo*|wlan*)
ip4=$(ip -4 -o addr show "$iface" 2>/dev/null | awk '{print $4}')
ssid=""
[ "$state" = "UP" ] && ssid=$(iwgetid -r "$iface" 2>/dev/null || true)
@@ -335,23 +365,31 @@ detect_displayserver() {
}
# ---------------------------------------
# Storage summary via lsblk (NVMe / SSD / HDD)
# Storage summary via lsblk (NVMe / SSD / HDD / USB-SD)
# ---------------------------------------
detect_storage() {
local parts=()
local name size rota type
local name size rota type rm
while read -r name size rota; do
while read -r name size rota type; do
[ "$name" = "NAME" ] && continue
echo "$name" | grep -q "zram" && continue
[ "$type" = "loop" ] || [ "$type" = "rom" ] && continue
if echo "$name" | grep -q "nvme"; then
type="NVMe"
elif [ "$rota" = "1" ]; then
type="HDD"
else
rm=$(cat /sys/block/"$name"/removable 2>/dev/null || echo 0)
if [ "$rm" = "1" ]; then
type="USB/SD"
else
type="SSD"
fi
fi
parts+=("${size} ${type}")
done < <(lsblk -d -o NAME,SIZE,ROTA 2>/dev/null || true)
done < <(lsblk -d -o NAME,SIZE,ROTA,TYPE -e 7,11 2>/dev/null || true)
if [ ${#parts[@]} -eq 0 ]; then
STORAGE_SUMMARY="No disks detected"
@@ -505,16 +543,56 @@ _confirm_custom() {
}
_msg() {
whiptail --title "$1" --msgbox "$2" "${3:-10}" "${4:-65}"
whiptail --title "$1" --msgbox "$2" "${3:-10}" "${4:-65}" || true
}
# Blocks 2-4: clear → run → pause
_msg_red() {
whiptail --colors --title "\Z1$1\Zn" --msgbox "\Z1$2\Zn" "${3:-12}" "${4:-70}" || true
}
_menu() {
local title="$1" text="$2" h="$3" w="$4" lh="$5"; shift 5
whiptail --title "$title" --menu "$text" "$h" "$w" "$lh" "$@" 3>&1 1>&2 2>&3 || true
}
_checklist() {
local title="$1" text="$2" h="$3" w="$4" lh="$5"; shift 5
whiptail --title "$title" --checklist "$text" "$h" "$w" "$lh" "$@" 3>&1 1>&2 2>&3 || true
}
_inputbox() {
whiptail --title "$1" --inputbox "$2" "${3:-10}" "${4:-60}" "${5:-}" 3>&1 1>&2 2>&3 || true
}
_validate_sudoers() {
local content="$1" dest="$2"
local tmpfile
tmpfile=$(mktemp) || return 1
echo "$content" > "$tmpfile"
if ! /usr/sbin/visudo -cf "$tmpfile" &>/dev/null; then
local err
err=$(/usr/sbin/visudo -cf "$tmpfile" 2>&1 || true)
rm -f "$tmpfile"
_msg "Sudoers Error" "Invalid sudoers syntax in:\n\n${err}\n\nFile was NOT written.\nThis prevents broken sudo access." 12 70
return 1
fi
sudo cp "$tmpfile" "$dest"
sudo chmod 0440 "$dest"
rm -f "$tmpfile"
}
_pause() {
local msg="${1:-Press Enter to continue...}"
echo -e "$msg"
read -r || true
}
# Blocks 2-4: run → pause
_run_cmd() {
local title="$1" command="$2" success_msg="${3:-Running...}"
clear
echo -e "${GREEN}[+]${NC} $success_msg"
echo "──────────────────────────────────────────────"
eval "$command"
bash -c "$command"
local rc=$?
echo "──────────────────────────────────────────────"
if [ $rc -eq 0 ]; then
@@ -522,11 +600,10 @@ _run_cmd() {
else
echo -e "${RED}[-]${NC} Failed (exit code: $rc)."
fi
echo "Press [ENTER] to continue..."
read -r
_pause
}
# Blocks 1-4: confirm → clear → run → pause
# Blocks 1-4: confirm → run → pause
_run() {
if _confirm "$1" "$2"; then
_run_cmd "$1" "$3" "$4"
@@ -581,3 +658,84 @@ get_backports_kernel_version() {
echo "unknown"
fi
}
# ----------------------------------
# Language helpers
# ----------------------------------
_detect_lang() {
local sys_lang
sys_lang=$(echo "${LANG:-en}" | cut -c1-2 | tr '[:upper:]' '[:lower:]')
echo "$sys_lang"
}
_detect_lang_pkg() {
local base="$1"
local lang2
lang2=$(_detect_lang)
[ "$lang2" = "en" ] && echo "" && return
local full="${LANG%%.*}"
local hyphenated_full
hyphenated_full=$(echo "$full" | tr '[:upper:]' '[:lower:]' | tr '_' '-')
local pkg
pkg=$(apt-cache search "^${base}-${hyphenated_full}$" 2>/dev/null | awk 'NR==1{print $1}')
[ -z "$pkg" ] && pkg=$(apt-cache search "^${base}-${lang2}$" 2>/dev/null | awk 'NR==1{print $1}')
[ -z "$pkg" ] && pkg=$(apt-cache search "^${base}-all$" 2>/dev/null | awk 'NR==1{print $1}')
echo "$pkg"
}
# ----------------------------------
# Network connectivity check
# ----------------------------------
_check_network() {
local target="${1:-deb.debian.org}"
if command -v ping &>/dev/null; then
ping -c 1 -W 3 "$target" &>/dev/null && return 0
fi
if command -v wget &>/dev/null; then
wget -q --timeout=5 --spider "http://${target}" &>/dev/null && return 0
fi
if command -v curl &>/dev/null; then
curl -s --connect-timeout 5 -o /dev/null "http://${target}" &>/dev/null && return 0
fi
return 1
}
# ----------------------------------
# LightDM configuration
# ----------------------------------
_configure_lightdm() {
command -v lightdm &>/dev/null || return 0
if _confirm "LightDM" "Configure LightDM to show the user list on the login screen?\n\nThis disables greeter-hide-users."; then
if ! is_installed lightdm-gtk-greeter-settings; then
echo -e "${YELLOW}Installing lightdm-gtk-greeter-settings...${NC}"
sudo DEBIAN_FRONTEND=noninteractive apt install -y lightdm-gtk-greeter-settings
fi
local conf_dir="/etc/lightdm/lightdm.conf.d"
local conf_file="${conf_dir}/99-show-users.conf"
if [ -f "$conf_file" ] && grep -q '^greeter-hide-users=false' "$conf_file"; then
return
fi
sudo mkdir -p "$conf_dir"
printf '[Seat:*]\ngreeter-hide-users=false\n' | sudo tee "$conf_file" > /dev/null
echo -e "${GREEN}LightDM configured to show user list.${NC}"
fi
}
# ── Lazy system state refresh ──
refresh_system_state() {
detect_debian_version
detect_gpu
detect_cpu_ram
}
+4 -5
View File
@@ -12,7 +12,7 @@ install_zram() {
local half_ram_mb=$(( ((RAM_KB / 1024 / 1024 + 1) / 2) * 1024 ))
local algo
algo=$(whiptail --title "ZRAM Compression" --menu \
algo=$(_menu "ZRAM Compression" \
"ZRAM compresses a portion of RAM into compressed swap,\
effectively increasing available memory.
@@ -22,8 +22,7 @@ more swap space without disk writes.
Choose compression algorithm:" \
$TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
"lz4" "Fastest, low CPU (recommended)" \
"zstd" "Better ratio, more CPU" \
3>&1 1>&2 2>&3)
"zstd" "Better ratio, more CPU")
if [ -z "$algo" ]; then
echo "ZRAM configuration cancelled."
@@ -34,8 +33,7 @@ Choose compression algorithm:" \
if _confirm "ZRAM Size" "Use recommended size for ZRAM? (${half_ram_mb} MB out of ${RAM_SUMMARY})"; then
zram_size=$half_ram_mb
else
zram_size=$(whiptail --title "ZRAM Size" --inputbox \
"Enter ZRAM size in MB:" 8 60 "$half_ram_mb" 3>&1 1>&2 2>&3)
zram_size=$(_inputbox "ZRAM Size" "Enter ZRAM size in MB:" 8 60 "$half_ram_mb")
if [ -z "$zram_size" ] || ! [[ "$zram_size" =~ ^[0-9]+$ ]] || [ "$zram_size" -eq 0 ]; then
echo "ZRAM configuration cancelled."
return 0
@@ -65,4 +63,5 @@ EOF
sudo zramctl
echo ""
echo -e "${GREEN}You can verify with: sudo zramctl${NC}"
_pause
}