add Java JDK/JRE selection and patches

- Created dedicated `extras/java.sh` module for modular Temurin/Adoptium repository handling and isolated GPG key management.
- Implemented selective JRE/JDK installation paths: Gaming (Minecraft) vs Development environments with version control selectors.
- Enhanced user group membership logic (`_ensure_sudo_group`) to auto-configure administrative privileges on fresh installs.
- Introduced maintenance-friendly passwordless sudo for `apt`, `systemctl`, and shutdown commands via `/etc/sudoers.d/`.
- Added home directory ownership repair utility to fix root-owned files in user directories after improper `sudo` usage.
- Enabled visual password feedback (`pwfeedback`) toggle for enhanced terminal usability during authentication prompts.
- Refactored Debian 13/Trixie repository sourcing logic to ensure idempotency and prevent backports/duplicate sources conflicts.
- Updated Bullseye legacy modules (extras.sh, repos.sh) to exclude deprecated packages (`hx`, `vscodium`) and enforce Firefox ESR defaults.
- Cleaned repository configurations by removing obsolete `bullseye-updates` source entries to prevent dependency conflicts.
- Implemented NVTOP conditional detection logic ensuring display only on active Nvidia drivers or supported architectures (Trixie/Bookworm).
- Corrected `/modules/bullseye/extras.sh` menu mappings (Programming, Dev Tools) and verified package lists excluding incompatible tools (`hx`, `vscodium`).
- Integrated ClamAV security module with daemon state management and background scan execution flows in all Security menus.
- update README.md
This commit is contained in:
stornic56
2026-06-13 19:21:55 -05:00
committed by GitHub
parent 656f045163
commit 872f92d6b4
16 changed files with 1037 additions and 357 deletions
+94 -59
View File
@@ -47,34 +47,54 @@ After running the script:
| Option | Description | What it does |
|--------|-------------|--------------|
| **1** | System Info | Show detected Os, CPU, RAM, GPU and others |
| **2** | User Privileges & Feedback | Add user to sudo group, enable `pwfeedback` for password visibility |
| **1** | System Info | Show detected OS, CPU, RAM, GPU and hardware details |
| **2** | [User Privileges & Feedback](#user-privileges--feedback) | 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 | Setup official repos with/without backports (deb822 or classic format)|
| **4** | Setup Wireless & Firmware | Install WiFi firmware for Broadcom, Intel, and other chipsets|
| **5** | Configure Graphics Stack | AMD/Intel/NVIDIA drivers + monitoring tools |
| **6** | Update Kernel to Backports | Install latest stable kernel from Debian backports|
| **7** | Gaming Setup and Performance | Steam, Heroic Games Launcher, GameMode, MangoHud and others|
| **7** | Gaming Setup and Performance | Steam, Heroic Games Launcher, GameMode, MangoHud, Java JRE (Temurin 8/17/21) |
| **8** | Install ZRAM (compressed swap) | Configure compressed RAM for memory optimization|
| **9** | Install Programs and Software | Selection across 10 categories (Dev, Themes, System, etc.) |
| **10** | Exit | Return to terminal |
### Extra Applications Categories (Option 9)
The submenu offers 11 categories:
The submenu offers the next categories:
| Option | Category | Description |
|--------|----------|-------------|
| Option | Category Title | Description |
|--------|-------------------------------|-------------|
| **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 (Firefox/Mozilla, LibreWolf, Floorp, Chromium), email clients, VPN tools|
| **4** | Media Players | VLC and MPV|
| **5** | Multimedia & Design | GIMP, Kdenlive, Blender, OBS Studio, Audacity, Inkscape and HandBrake|
| **6** | Programming Applications | Development tools (Docker, Nginx/Apache, PostgreSQL/MariaDB, SSH, fail2ban, Python)|
| **7** | Security & Networking | Additional security and networking utilities |
| **8** | System Tools | htop, btop, ncdu, timeshift, tmux, flatpak, extrepo and virtualization tools|
| **9** | Fetch / System Info | Fastfetch/Neofetch, hyfetch, Linux logo and Screenfetch |
| **10** | Back to main menu | Return to the main script menu |
| **3** | Internet (Browsers, Email Clients, VPN Tools) | Web browsers (Firefox/Mozilla, LibreWolf, Floorp, Chromium, Brave, Tor), email clients (Thunderbird), and VPN tools including Riseup |
| **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, and essential utilities |
| **8** | Security & Networking | Wireshark, tcpdump, Zenmap, ClamAV, UFW, Fail2ban |
| **9** | System Tools | htop/btop, ncdu, Timeshift, tmux/screen, Flatpak support, extension repository manager, and qemu/virtmanager |
| **10** | Fetch / System Info | fastfetch/neofetch, hyfetch, Linux logo and screenfetch |
| **11** | Back to Main Menu | Return directly to the main Debianito menu (exit submenu) |
---
## User Privileges & Feedback
Admin rights, passwordless commands, and file ownership fixes—optimized for Debian users.
### 1. Sudo Group Membership
If you just installed Debian and cant install software or change system settings (you get "Permission denied"), this option adds your user to the sudo group. This gives you admin privileges so you can manage your system. Changes take effect after you log out and back in.
### 2. Passwordless Sudo for Frequent Tasks
Every time you run sudo apt install or sudo reboot, Linux asks for your password. This option lets you skip typing your password for common commands like installing/updating software (apt), restarting or shutting down (systemctl).
- ⚠️ Security Note: While convenient, this reduces security if someone else uses your PC physically.
### 3. Repair Home Directory Ownership
Sometimes, when you use sudo incorrectly (e.g., installing games or apps), files get "stolen" by the system (root) instead of your user. This causes apps to fail (e.g., saving settings or game progress). This option fixes ownership so all your files and folders belong to you again.
### 4. Sudo Password Feedback (Asterisks)
By default, Debians terminal hides your password (no asterisks or feedback). This option adds visual feedback (e.g., ****) so you can see how many characters youve typed. Toggle it on/off as needed.
---
@@ -87,52 +107,67 @@ The submenu offers 11 categories:
| `/modules/extras/` | Split-by-category sub-modules for the "Install Programs and Software" menu (Option 9). |
```bash
├── debianito.sh # Main entry point; TUI menu + system detection
├── modules/
├── utils.sh # System info helpers: CPU/RAM/GPU/WiFi detection, Debian version check ([`detect_debian_version()`](utils.sh#L79))
├── sudo_config.sh # User group + pwfeedback setup
├── repos.sh # Repository configuration (deb822/classic format) with backup/restore
├── firmware.sh # WiFi microcode and chipset-specific support via [`firmware-linux-nonfree`](modules/firmware.sh)
├── gpu.sh # AMD/Intel/NVIDIA driver handling ([`detect_gpu()`](utils.sh#L168)); NVIDIA Kepler/Turing detection veto (line 203+)
├── kernel.sh # Update Kernel to Backports with NVIDIA compatibility warnings
├── gaming.sh # Steam, GameMode, MangoHud, Heroic Games Launcher
├── zram.sh # ZRAM compressed swap configuration
├── gpu/ # NVIDIA-specific modules for Debian 12+ (Bookworm/Trixie)
│ ├── _helpers.sh # Shared helpers including [`is_nvidia_kepler()`](gpu/_helpers.sh#LXX) with four isolated blocks for legacy detection
│ └── nvidia.sh # NVIDIA driver installation ([`_install_nvidia_bookworm_kepler()`](gpu/nvidia.sh#LXX))
├── bullseye/ # Legacy support modules for Debian 11 (Bullseye) with ultra-minimalist rescue environment
│ ├── legacy.sh # Fermi GPU detection (NVIDIA-390xx drivers), [install_gaming_bullseye](bullseye/legacy.sh#LXX) function
│ ├── repos.sh # Classic `/etc/apt/sources.list` format with Archive Phase 2026 configuration
│ └── extras.sh # Utilities installation with purged package list for unavailable packages on Debian 11
└── extras/ # Category modules organized by function (Option 9 submenu)
├── _helpers.sh # Shared helpers: [`_inst()`](utils.sh#L418), [`_state()`] for package management
├── essential/ # Essential Pack (compression, system info, VLC, MS fonts)
│ └── essential.sh # One-click essentials installation
├── system/ # System Tools (htop, btop, ncdu, timeshift, tmux, flatpak, extrepo, virtualization tools)
│ └── system.sh # 25+ system utility packages
├── dev/ # Development & Servers (Docker, Nginx/Apache, PostgreSQL/MariaDB, SSH, fail2ban, Python)
│ └── dev.sh # 15 development/server tools
├── players/ # Media Players (VLC, MPV)
│ └── players.sh # Video player packages
├── internet/ # Internet: Firefox (Mozilla), LibreWolf, Floorp, Chromium, Thunderbird, Riseup VPN, Tor Browser
│ └── internet.sh # Browsers, email clients, VPN tools
── themes/ # Customization submenu with 4 options
├── themes.sh # Submenu dispatcher for customization categories
│ ├── desktop-themes/ # Desktop Themes (GTK/KDE): Arc, Numix, Breeze GTK, Bluebird, Blackbird, Greybird, Orchis
── desktop-themes.sh
│ ├── icons/ # Icon Themes: Papirus, Numix, Elementary, Deepin, Suru, Obsidian, Breeze, Moka
── icons.sh # 11-12 icon theme packages
│ ├── cursors/ # Cursor Themes: Bibata, Breeze, Chameleon, DMZ, XCursor, Oxygen
── cursors.sh # 6 cursor theme packages
└── fonts/ # Fonts: Bebas Neue, Anonymous Pro, ADF Verana, 3270, Liberation, MS Core, Ubuntu, Recommended
│ └── fonts.sh # 8 font packages including MS Core fonts
├── fetch/ # Fetch Tools (Neofetch/Fastfetch, hyfetch, Linux logo, Screenfetch)
│ └── fetch.sh # System info display tools
├── download/ # Downloaders & Torrent Clients: aria2, ytdlp, FileZilla, qBittorrent, Deluge, Transmission, mktorrent
│ └── download.sh # Download manager + torrent client packages
└── design/ # Multimedia & Design (GIMP, Kdenlive, Blender, OBS Studio, Audacity, Inkscape, HandBrake)
└── design.sh # 12+ creative applications
├── debianito.sh
├── modules
   ├── bullseye
   │   ├── extras.sh
   │   ├── legacy.sh
   │   └── repos.sh
   ├── extras
   │   ├── design
   │   │   └── design.sh
   │   ├── dev
   │   │   └── dev.sh
   │   ├── download
   │   │   └── download.sh
   │   ├── essential
   │   │   └── essential.sh
   │   ├── fetch
   │   │   └── fetch.sh
   │   ├── _helpers.sh
   │   ├── internet
   │   │   └── internet.sh
   │   ├── java.sh
   │   ├── players
   │   │   └── players.sh
   │   ├── programming
   │   │   └── programming.sh
   │   ├── security
   │   │   └── security.sh
   │   ├── system
   │   │   └── system.sh
   │  ── themes
   │   ├── cursors
   │   │   └── cursors.sh
   │   ── desktop-themes
   │   │   └── desktop-themes.sh
   │   ── fonts
   │   │   └── fonts.sh
   │   ── icons
   │     └── icons.sh
   │   └── themes.sh
   ├── extras.sh
   ├── firmware.sh
   ├── gaming
   │   ├── _helpers.sh
   │   ├── heroic.sh
   │   ├── steam.sh
│   │   └── tools.sh
│   ├── gaming.sh
│   ├── gpu
│   │   ├── amd_intel.sh
│   │   ├── _helpers.sh
│   │   └── nvidia.sh
│   ├── gpu.sh
│   ├── kernel.sh
│   ├── repos.sh
│   ├── sudo_config.sh
│   ├── utils.sh
│   └── zram.sh
└── README.md
```
---
> 🤖 **AI-Assisted Development Note**
> This project was developed with assistance from large language models for code generation, documentation and testing suggestions. The author takes full responsibility for the accuracy of all scripts included in this repository. All modifications have been reviewed manually before inclusion to ensure compatibility with Debian systems.
+2
View File
@@ -17,6 +17,7 @@ MODULES_DIR="${SCRIPT_DIR}/modules"
source "${MODULES_DIR}/utils.sh"
source "${MODULES_DIR}/sudo_config.sh"
source "${MODULES_DIR}/repos/repo_detect.sh"
source "${MODULES_DIR}/repos.sh"
[ -f "${MODULES_DIR}/firmware.sh" ] && source "${MODULES_DIR}/firmware.sh"
[ -f "${MODULES_DIR}/gpu.sh" ] && source "${MODULES_DIR}/gpu.sh"
@@ -24,6 +25,7 @@ source "${MODULES_DIR}/repos.sh"
[ -f "${MODULES_DIR}/gaming.sh" ] && source "${MODULES_DIR}/gaming.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"
# ── Bullseye-specific modules (loaded only on Debian 11) ──
if [ -d "${MODULES_DIR}/bullseye" ]; then
+172 -86
View File
@@ -49,8 +49,6 @@ Instalar?"; then
# ======================================================================
_cat_customization_bullseye() {
local items=()
if [ -f "${MODULES_DIR}/extras/themes/icons/icons.sh" ]; then
local TUI_ANCHO_REFORZADO=$((TUI_ANCHO + 6))
local sub
sub=$(whiptail --title "Customization (Bullseye)" --menu \
@@ -67,25 +65,18 @@ _cat_customization_bullseye() {
3) _cat_cursors_bullseye ;;
4) _cat_fonts_bullseye ;;
esac
else
_msg "Customization" "Themes submodules not found." 8 50
fi
}
_cat_themes_bullseye() {
local theme_state; theme_state=$(_state "breeze")
local numix_state; numix_state=$(_state "numix-gtk-theme")
if [ "$theme_state" = "OFF" ] && [ "$numix_state" = "OFF" ]; then
theme_state="ON"
fi
local choices
choices=$(whiptail --title "Desktop Themes (Bullseye)" --checklist \
"Available themes in Bullseye repos ($TUI_ALTO linea):" \
$TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
"breeze" "Breeze GTK theme (KDE)$(_inst breeze)" "$theme_state" \
"numix-gtk-theme" "Numix GTK theme$(_inst numix-gtk-theme)" "$numix_state" \
"Select desktop themes:" $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)
clear
[ -z "$choices" ] && return
@@ -97,19 +88,21 @@ _cat_themes_bullseye() {
}
_cat_icons_bullseye() {
_msg "Icon Themes (Bullseye)" \
"Adwaita, Humanity, DMZ y otros temas de iconos\n\
están disponibles desde los repos oficiales.\n\n\
Seleccione desde el menú de GNOME/KDE o instale\n\
el paquete 'gnome-icon-theme' o 'breeze-icon-theme'." 12 60
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)"
)
local choices
choices=$(whiptail --title "Icon Themes (Bullseye)" --checklist \
"Available icon themes:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
"gnome-icon-theme" "GNOME icon theme$(_inst gnome-icon-theme)" "$(_state gnome-icon-theme)" \
"breeze-icon-theme" "Breeze icon theme$(_inst breeze-icon-theme)" "$(_state breeze-icon-theme)" \
"papirus-icon-theme" "Papirus icon theme$(_inst papirus-icon-theme)" "$(_state papirus-icon-theme)" \
3>&1 1>&2 2>&3)
"Select icon themes:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
"${items[@]}" 3>&1 1>&2 2>&3)
clear
[ -z "$choices" ] && return
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
@@ -122,10 +115,12 @@ el paquete 'gnome-icon-theme' o 'breeze-icon-theme'." 12 60
_cat_cursors_bullseye() {
local choices
choices=$(whiptail --title "Cursor Themes (Bullseye)" --checklist \
"Available cursor themes:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
"dmz-cursor-theme" "DMZ cursor theme$(_inst dmz-cursor-theme)" "$(_state dmz-cursor-theme)" \
"breeze-cursor-theme" "Breeze cursor theme$(_inst breeze-cursor-theme)" "$(_state breeze-cursor-theme)" \
"oxygen-cursor-theme" "Oxygen cursor theme$(_inst oxygen-cursor-theme)" "$(_state oxygen-cursor-theme)" \
"Select cursor themes:" $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)
clear
[ -z "$choices" ] && return
@@ -155,19 +150,32 @@ _cat_fonts_bullseye() {
}
_cat_download_bullseye() {
local choices
choices=$(whiptail --title "Download & Torrent (Bullseye)" --checklist \
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)" \
"qbittorrent" "BitTorrent client (Qt)$(_inst qbittorrent)" "$(_state qbittorrent)" \
"transmission-gtk" "BitTorrent client (GTK)$(_inst transmission-gtk)" "$(_state transmission-gtk)" \
"transmission-qt" "BitTorrent client (Qt)$(_inst transmission-qt)" "$(_state transmission-qt)" \
"deluge" "BitTorrent client (GTK)$(_inst deluge)" "$(_state deluge)" \
3>&1 1>&2 2>&3)
clear
[ -z "$choices" ] && return
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
choices2=$(whiptail --title "Torrent Clients" --checklist \
"Select torrent clients:" $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)
clear
local cleaned
cleaned=$(echo "$choices1 $choices2" | tr -d '"')
[ -z "$cleaned" ] && { echo "No download tools selected."; return; }
for pkg in $cleaned; do
if ! is_installed "$pkg"; then
_run_install "$pkg"
@@ -175,35 +183,46 @@ _cat_download_bullseye() {
echo "$pkg already installed."
fi
done
echo -e "${GREEN}Download tools installed.${NC}"
echo -e "${GREEN}Download & network tools installed.${NC}"
}
_cat_internet_bullseye() {
local ff_state; ff_state=$(_state "firefox-esr")
local tbird_state; tbird_state=$(_state "thunderbird")
local chr_state; chr_state=$(_state "chromium")
local choices
choices=$(whiptail --title "Internet (Bullseye)" --checklist \
"Select browsers, email:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
"firefox-esr" "Firefox ESR (official Debian)$(_inst firefox-esr)" "$ff_state" \
"chromium" "Chromium web browser$(_inst chromium)" "$chr_state" \
"thunderbird" "Email client$(_inst thunderbird)" "$tbird_state" \
"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)" \
"w3m" "Text-mode browser + deps$(_inst w3m)" "$(_state w3m)" \
"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)
clear
[ -z "$choices" ] && return
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
for pkg in $cleaned; do
case $pkg in
w3m)
local need=()
! is_installed "w3m" && need+=("w3m")
! is_installed "w3m-img" && need+=("w3m-img")
! is_installed "ca-certificates" && need+=("ca-certificates")
! is_installed "xsel" && need+=("xsel")
[ ${#need[@]} -gt 0 ] && _run_install_batch "${need[@]}" || echo "Already installed."
;;
*)
if ! is_installed "$pkg"; then
_run_install "$pkg"
else
echo "$pkg already installed."
fi
;;
esac
done
echo -e "${GREEN}Internet tools installed.${NC}"
}
@@ -232,14 +251,19 @@ _cat_design_bullseye() {
local choices
choices=$(whiptail --title "Multimedia & Design (Bullseye)" --checklist \
"Select multimedia and design tools:" $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)" \
"obs-studio" "Streaming/recording studio$(_inst obs-studio)" "$(_state obs-studio)" \
"scribus" "Desktop publishing$(_inst scribus)" "$(_state scribus)" \
"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)
clear
[ -z "$choices" ] && return
@@ -251,24 +275,22 @@ _cat_design_bullseye() {
echo "$pkg already installed."
fi
done
echo -e "${GREEN}Design tools installed.${NC}"
echo -e "${GREEN}Multimedia & design tools installed.${NC}"
}
_cat_programming_bullseye() {
local choices
choices=$(whiptail --title "Programming (Bullseye)" --checklist \
"Select programming tools:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
"build-essential" "GCC/Clang compilers$(_inst build-essential)" "$(_state build-essential)" \
"python3" "Python 3 interpreter$(_inst python3)" "$(_state python3)" \
"python3-pip" "Python 3 package manager$(_inst python3-pip)" "$(_state python3-pip)" \
"nodejs" "Node.js (Debian repo)$(_inst nodejs)" "$(_state nodejs)" \
"npm" "Node.js package manager$(_inst npm)" "$(_state npm)" \
"openjdk-17-jdk" "OpenJDK 17 JDK$(_inst openjdk-17-jdk)" "$(_state openjdk-17-jdk)" \
"git" "Version control system$(_inst git)" "$(_state git)" \
"vim" "Text editor (Vim)$(_inst vim)" "$(_state vim)" \
"nano" "Text editor (Nano)$(_inst nano)" "$(_state nano)" \
choices=$(whiptail --title "Code Editors & IDEs (Bullseye)" --checklist \
"Select editors and IDEs:" $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)" \
"codeblocks" "Cross-platform IDE$(_inst codeblocks)" "$(_state codeblocks)" \
3>&1 1>&2 2>&3)
clear
[ -z "$choices" ] && return
@@ -280,33 +302,96 @@ _cat_programming_bullseye() {
echo "$pkg already installed."
fi
done
echo -e "${GREEN}Programming tools installed.${NC}"
echo -e "${GREEN}Code editors & IDEs installed.${NC}"
}
_cat_dev_bullseye() {
local choices
choices=$(whiptail --title "Servers & Dev Tools (Bullseye)" --checklist \
"Select development tools and servers:" $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)" \
"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 '"')
for pkg in $cleaned; do
case $pkg in
docker)
local need=()
! is_installed "docker.io" && need+=("docker.io")
! is_installed "docker-compose" && need+=("docker-compose")
if [ ${#need[@]} -gt 0 ]; then
_run_install_batch "${need[@]}"
else
echo "Docker already installed."
fi
;;
python3-pip)
local need=()
! is_installed "python3-pip" && need+=("python3-pip")
! is_installed "python3-venv" && need+=("python3-venv")
! is_installed "python3-dev" && need+=("python3-dev")
if [ ${#need[@]} -gt 0 ]; then
_run_install_batch "${need[@]}"
else
echo "Python 3 tools already installed."
fi
;;
openjdk-dev-env)
_install_dev_java
;;
*)
if ! is_installed "$pkg"; then
_run_install "$pkg"
else
echo "$pkg already installed."
fi
;;
esac
done
echo -e "${GREEN}Servers & dev tools installed.${NC}"
}
_cat_security_bullseye() {
local choices
choices=$(whiptail --title "Security & Networking (Bullseye)" --checklist \
"Select security tools:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
"nmap" "Network scanner$(_inst nmap)" "$(_state nmap)" \
"wireshark" "Packet analyzer$(_inst wireshark)" "$(_state wireshark)" \
"nikto" "Web server scanner$(_inst nikto)" "$(_state nikto)" \
"sqlmap" "SQL injection tool$(_inst sqlmap)" "$(_state sqlmap)" \
"gobuster" "Directory/file brute-forcer$(_inst gobuster)" "$(_state gobuster)" \
"hydra" "Login cracker$(_inst hydra)" "$(_state hydra)" \
"john" "John the Ripper password cracker$(_inst john)" "$(_state john)" \
"aircrack-ng" "Wireless security tool$(_inst aircrack-ng)" "$(_state aircrack-ng)" \
"Select security and networking tools:" $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)
clear
[ -z "$choices" ] && return
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
for pkg in $cleaned; do
case $pkg in
clamav)
_install_clamav
;;
*)
if ! is_installed "$pkg"; then
_run_install "$pkg"
else
echo "$pkg already installed."
fi
;;
esac
done
echo -e "${GREEN}Security tools installed.${NC}"
echo -e "${GREEN}Security & networking tools installed.${NC}"
}
_cat_general_bullseye() {
@@ -345,9 +430,7 @@ _cat_general_bullseye() {
! is_installed "unrar" && need+=("unrar")
! is_installed "p7zip-full" && need+=("p7zip-full")
! is_installed "p7zip-rar" && need+=("p7zip-rar")
if [ ${#need[@]} -gt 0 ]; then
_run_install_batch "${need[@]}"
fi
[ ${#need[@]} -gt 0 ] && _run_install_batch "${need[@]}"
;;
curl-wget)
local need=()
@@ -436,6 +519,7 @@ _cat_fetch_bullseye() {
# ======================================================================
install_extras_bullseye() {
echo -e "${YELLOW}Extra software — Bullseye mode (official repos only).${NC}"
_load_extras
while true; do
local cat_choice
@@ -447,11 +531,12 @@ install_extras_bullseye() {
"3" "Internet (Browsers, Email)" \
"4" "Media Players" \
"5" "Multimedia & Design" \
"6" "Programming Applications" \
"7" "Security & Networking" \
"8" "System Tools" \
"9" "Fetch / System Info" \
"10" "Back to main menu" \
"6" "Code Editors & IDEs" \
"7" "Servers & Dev Tools" \
"8" "Security & Networking" \
"9" "System Tools" \
"10" "Fetch / System Info" \
"11" "Back to main menu" \
3>&1 1>&2 2>&3)
[ -z "$cat_choice" ] && return
@@ -465,10 +550,11 @@ install_extras_bullseye() {
4) _cat_players_bullseye ;;
5) _cat_design_bullseye ;;
6) _cat_programming_bullseye ;;
7) _cat_security_bullseye ;;
8) _cat_general_bullseye ;;
9) _cat_fetch_bullseye ;;
10) return ;;
7) _cat_dev_bullseye ;;
8) _cat_security_bullseye ;;
9) _cat_general_bullseye ;;
10) _cat_fetch_bullseye ;;
11) return ;;
esac
clear
done
+18 -16
View File
@@ -116,18 +116,18 @@ install_gaming_bullseye() {
local enable_32bit=false
if _confirm "32-bit Support" \
"Habilitar arquitectura i386 para juegos?\n\n\
Requieren los juegos nativos de 32 bits y ciertas\n\
bibliotecas de emulación."; then
"Enable i386 architecture for 32-bit games?\n\n\
Required by Steam/Proton for 32-bit games.\n\
Installs matching 32-bit graphics drivers."; then
enable_32bit=true
fi
if $enable_32bit; then
echo "Activando soporte multiarquitectura i386..."
echo "Enabling i386 multi-architecture support..."
if ! dpkg --print-foreign-architectures | grep -q i386; then
sudo dpkg --add-architecture i386
fi
_run_cmd "APT Update" "sudo apt update" "Actualizando listas..."
_run_cmd "APT Update" "sudo apt update" "Updating package lists..."
if [ "$GPU_TYPE" = "nvidia" ]; then
local nv32_pkg="nvidia-driver-libs:i386"
@@ -139,10 +139,10 @@ bibliotecas de emulación."; then
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}" \
"Instalando librerías NVIDIA 32-bit..."
"Installing NVIDIA 32-bit libraries..."
fi
else
echo "nvidia-driver-libs:i386 no disponible en Bullseye."
echo "nvidia-driver-libs:i386 not available on Bullseye."
fi
else
# Mesa 32-bit
@@ -158,20 +158,20 @@ bibliotecas de emulación."; then
awk 'NR==3 {print $2; exit}')
local comp_line="Components: Vulkan:i386, OpenGL:i386, GLX:i386, EGL:i386, VA-API:i386"
local msg="Mesa 32-bit drivers para gaming.\n\n"
local msg="Mesa 32-bit drivers for gaming.\n\n"
msg+="Source: Debian Bullseye Stable\n"
msg+="Mesa ${ref_ver}\n"
msg+="${comp_line}\n\n"
msg+="Instalar drivers 32-bit?"
msg+="Install 32-bit drivers?"
if _confirm "Mesa 32-bit" "$msg" 14 70; then
_run_cmd "Mesa 32-bit" "sudo apt install -y ${mesa_32[*]}" \
"Instalando Mesa 32-bit..."
"Installing Mesa 32-bit..."
fi
fi
fi
# Gaming tools checklist (sin Steam ni Heroic)
# Gaming tools checklist (no Steam, no Heroic)
local choices
choices=$(whiptail --title "Gaming Tools — Bullseye" --checklist \
"Select gaming optimization tools:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
@@ -179,6 +179,7 @@ bibliotecas de emulación."; then
"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)
if [ -z "$choices" ]; then
@@ -192,20 +193,21 @@ bibliotecas de emulación."; then
for pkg in $cleaned; do
case $pkg in
mangohud)
_run_cmd "MangoHud" "sudo apt install -y mangohud" "Instalando MangoHud..."
_run_cmd "MangoHud" "sudo apt install -y mangohud" "Installing 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" \
"Instalando MangoHud 32-bit..."
"Installing MangoHud 32-bit..."
fi
fi
;;
gamemode) _run_cmd "GameMode" "sudo apt install -y gamemode" "Instalando GameMode..." ;;
goverlay) _run_cmd "GOverlay" "sudo apt install -y goverlay" "Instalando GOverlay..." ;;
lutris) _run_cmd "Lutris" "sudo apt install -y lutris" "Instalando Lutris..." ;;
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..." ;;
java) _install_gaming_java ;;
*) _run_install "$pkg" ;;
esac
done
+12 -16
View File
@@ -5,19 +5,19 @@
configure_repos_bullseye() {
echo -e "${YELLOW}Repository configuration — Debian 11 Bullseye${NC}"
local info="Configuración de repositorios para Debian 11 Bullseye.\n\n"
info+="Se usarán los repositorios oficiales con componentes\n"
info+="main, contrib y non-free (sin non-free-firmware).\n"
info+="No se utiliza formato DEB822.\n"
local info="Repository configuration for Debian 11 Bullseye.\n\n"
info+="Official repositories will be used with components\n"
info+="main, contrib and non-free (non-free-firmware excluded).\n"
info+="DEB822 format is not used.\n"
if $BULLSEYE_USE_ARCHIVE; then
info+="\nModo Archive: Las URLs apuntarán a archive.debian.org\n"
info+="(Bullseye LTS finalizó el 31 Ago 2026)."
info+="\nArchive Mode: URLs will point to archive.debian.org\n"
info+="(Bullseye LTS ended on 31 Aug 2026)."
fi
_msg "Repositorios — Bullseye" "$info" 12 65
_msg "Repositories — Bullseye" "$info" 12 65
if [ -f /etc/apt/sources.list ]; then
if ! _confirm "Repositorios" "Ya existe /etc/apt/sources.list.\n\nSobrescribir con la configuración de Bullseye?"; then
echo "Manteniendo configuración actual."
if ! _confirm "Repositories" "/etc/apt/sources.list already exists.\n\nOverwrite with Bullseye configuration?"; then
echo "Keeping current configuration."
return 0
fi
fi
@@ -34,21 +34,17 @@ configure_repos_bullseye() {
content+="deb ${base_uri} bullseye main contrib non-free\n"
content+="#deb-src ${base_uri} bullseye main contrib non-free\n\n"
content+="# Updates\n"
content+="deb ${base_uri} bullseye-updates main contrib non-free\n"
content+="#deb-src ${base_uri} bullseye-updates main contrib non-free\n\n"
content+="# Security\n"
content+="deb ${security_uri} bullseye-security main contrib non-free\n"
content+="#deb-src ${security_uri} bullseye-security main contrib non-free\n"
echo -e "$content" | sudo tee /etc/apt/sources.list > /dev/null
echo "Actualizando listas de paquetes..."
echo "Updating package lists..."
if sudo apt update; then
echo -e "${GREEN}Repositorios de Debian 11 Bullseye configurados.${NC}"
echo -e "${GREEN}Debian 11 Bullseye repositories configured.${NC}"
else
echo -e "${RED}apt update falló. Revise su conexión de red.${NC}"
echo -e "${RED}apt update failed. Check your network connection.${NC}"
return 1
fi
}
+11 -9
View File
@@ -35,11 +35,12 @@ install_extras() {
"3" "Internet (Browsers, Email, VPN)" \
"4" "Media Players" \
"5" "Multimedia & Design" \
"6" "Programming Applications" \
"7" "Security & Networking" \
"8" "System Tools" \
"9" "Fetch / System Info" \
"10" "Back to main menu" \
"6" "Code Editors & IDEs" \
"7" "Servers & Dev Tools" \
"8" "Security & Networking" \
"9" "System Tools" \
"10" "Fetch / System Info" \
"11" "Back to main menu" \
3>&1 1>&2 2>&3)
[ -z "$cat_choice" ] && return
@@ -53,10 +54,11 @@ install_extras() {
4) _cat_players ;;
5) _cat_design ;;
6) _cat_programming ;;
7) _cat_security ;;
8) _cat_general ;;
9) _cat_fetch ;;
10) return ;;
7) _cat_dev ;;
8) _cat_security ;;
9) _cat_general ;;
10) _cat_fetch ;;
11) return ;;
esac
clear
done
+21
View File
@@ -8,3 +8,24 @@ _inst() {
_state() {
is_installed "$1" && echo "ON" || echo "OFF"
}
_install_clamav() {
if is_installed "clamav"; then
echo "ClamAV already installed."
return
fi
_run_install "clamav"
echo -e "${GREEN}ClamAV installed.${NC}"
if _confirm "ClamAV" "Update virus signatures now (freshclam)?"; then
sudo systemctl stop clamav-freshclam 2>/dev/null || true
sudo freshclam || true
sudo systemctl start clamav-freshclam 2>/dev/null || true
fi
if _confirm "ClamAV" "Run quick scan on /bin to verify engine works?"; then
echo "Running background scan on /bin..."
sudo clamscan --recursive --infected /bin &
echo "Scan running in background (PID $!). Check results later."
fi
}
+6
View File
@@ -17,6 +17,8 @@ _cat_dev() {
local pip_state; pip_state=$(_state "python3-pip")
local redis_state; redis_state=$(_state "redis-server")
local sqlite_state; sqlite_state=$(_state "sqlite3")
local jdk_desc; jdk_desc=$(_any_jdk_installed_desc)
local jdk_state; jdk_state=$(_any_jdk_state)
local TUI_ANCHO_REFORZADO=$((TUI_ANCHO + 6))
local choices
@@ -35,6 +37,7 @@ _cat_dev() {
"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" \
"openjdk-dev-env" "Adoptium Temurin JDK (17, 21, 25 LTS)${jdk_desc}" "${jdk_state}" \
3>&1 1>&2 2>&3)
clear
@@ -65,6 +68,9 @@ _cat_dev() {
echo "Docker already installed."
fi
;;
openjdk-dev-env)
_install_dev_java
;;
*)
if ! is_installed "$pkg"; then
_run_install "$pkg"
+62
View File
@@ -0,0 +1,62 @@
#!/usr/bin/env bash
# java.sh — Adoptium Temurin repository setup and Java version selectors
# License GPL v3
_ensure_adoptium_repo() {
[ -f /etc/apt/sources.list.d/adoptium.list ] && return 0
local deps=()
! is_installed "wget" && deps+=("wget")
! is_installed "apt-transport-https" && deps+=("apt-transport-https")
! is_installed "gpg" && deps+=("gpg")
[ ${#deps[@]} -gt 0 ] && _run_install_batch "${deps[@]}"
wget -qO - "https://packages.adoptium.net/artifactory/api/gpg/key/public" \
| sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/adoptium.gpg 2>/dev/null
local codename
codename=$(awk -F= '/^VERSION_CODENAME/{print$2}' /etc/os-release)
echo "deb https://packages.adoptium.net/artifactory/deb ${codename} main" \
| sudo tee /etc/apt/sources.list.d/adoptium.list > /dev/null
sudo apt update \
-o Dir::Etc::sourcelist=/etc/apt/sources.list.d/adoptium.list \
-o Dir::Etc::sourceparts="-" \
2>/dev/null || true
}
_install_gaming_java() {
local ver
ver=$(whiptail --title "Java Runtimes for Gaming" --menu \
"Select Java version:" 12 65 3 \
"8" "Java 8 — For classic mods & Minecraft <= 1.16.5" \
"17" "Java 17 — For Minecraft era 1.17 to 1.20.4" \
"21" "Java 21 — For modern Minecraft >= 1.20.5 & 1.21+" \
3>&1 1>&2 2>&3)
[ -z "$ver" ] && { echo "No Java version selected."; return; }
_ensure_adoptium_repo
_run_install "temurin-${ver}-jre"
}
_install_dev_java() {
local ver
ver=$(whiptail --title "Java Development Kits (JDK)" --menu \
"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)
[ -z "$ver" ] && { echo "No JDK version selected."; return; }
_ensure_adoptium_repo
_run_install "temurin-${ver}-jdk"
}
_any_jdk_installed_desc() {
local inst
inst=$(dpkg -l 'temurin-*-jdk' 2>/dev/null | awk '/^ii/ {print $2; exit}')
[ -n "$inst" ] && echo " ($inst installed)" || echo ""
}
_any_jdk_state() {
dpkg -l 'temurin-*-jdk' 2>/dev/null | grep -q '^ii' && echo "ON" || echo "OFF"
}
+6 -1
View File
@@ -9,16 +9,18 @@ _cat_security() {
local zenmap_state; zenmap_state=$(_state "zenmap")
local fail2ban_state; fail2ban_state=$(_state "fail2ban")
local ufw_state; ufw_state=$(_state "ufw")
local clamav_state; clamav_state=$(_state "clamav")
local TUI_ANCHO_REFORZADO=$((TUI_ANCHO + 6))
local choices
choices=$(whiptail --title "Security & Networking" --checklist \
"Select security and networking tools (5 items):" $TUI_ALTO $TUI_ANCHO_REFORZADO $TUI_ALTO_LISTA \
"Select security and networking tools (6 items):" $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)
clear
@@ -31,6 +33,9 @@ _cat_security() {
zenmap)
install_backports_or_stable zenmap
;;
clamav)
_install_clamav
;;
*)
if ! is_installed "$pkg"; then
_run_install "$pkg"
+2
View File
@@ -128,6 +128,7 @@ install_gaming() {
"gamemode" "Game performance optimization" ON \
"mangohud" "Performance overlay (Vulkan/OpenGL)" ON \
"heroic" "Heroic Launcher (Epic/GOG)" OFF \
"java-jre" "Java Runtimes (8, 17, 21)" OFF \
"goverlay" "MangoHud config GUI" ON \
"lutris" "Game launcher/manager" OFF \
3>&1 1>&2 2>&3)
@@ -157,6 +158,7 @@ install_gaming() {
fi
;;
heroic) install_heroic ;;
java) _install_gaming_java ;;
mangohud) install_mangohud ;;
gamemode) install_gamemode ;;
goverlay) install_goverlay ;;
+6
View File
@@ -134,6 +134,12 @@ install_mesa_stable() {
}
offer_generic_tools() {
if [ "$DEBIAN_VERSION" = "11" ]; then
if ! lsmod 2>/dev/null | grep -q "^nvidia "; then
echo "nvtop skipped on Bullseye — NVIDIA driver not loaded."
return
fi
fi
local tool_pkgs
tool_pkgs=$(pkg_versions nvtop vainfo)
if _confirm "GPU Tools" "Install monitoring and info tools?\n\n${tool_pkgs}"; then
+19
View File
@@ -20,7 +20,11 @@ offer_amd_tools() {
fi
local pkgs
if [ "$DEBIAN_VERSION" = "11" ]; then
pkgs=$(pkg_versions "${amd_tools[@]}" vainfo)
else
pkgs=$(pkg_versions "${amd_tools[@]}" nvtop vainfo)
fi
if $corectrl_available; then
local ctrl_ver
ctrl_ver=$(apt-cache policy corectrl 2>/dev/null | awk 'NR==3 {print $2; exit}')
@@ -32,7 +36,11 @@ offer_amd_tools() {
return
fi
if [ "$DEBIAN_VERSION" = "11" ]; then
_run_cmd "AMD Tools" "sudo apt install -y ${amd_tools[*]} vainfo" "Installing AMD tools..."
else
_run_cmd "AMD Tools" "sudo apt install -y ${amd_tools[*]} nvtop vainfo" "Installing AMD tools..."
fi
vainfo
if $corectrl_available; then
@@ -73,7 +81,18 @@ offer_intel_tools() {
[ -d "/sys/bus/pci/drivers/xe" ] && has_xe=true
[ -d "/sys/bus/pci/drivers/i915" ] && has_i915=true
if [ "$DEBIAN_VERSION" = "11" ]; then
if $has_xe; then
echo "Intel Xe GPU detected. No monitoring tools available on Bullseye."
return
elif $has_i915; then
driver_info="Classic Intel GPU detected (i915 driver)."
pkg_list=("intel-gpu-tools")
else
echo "Intel GPU driver not identified. No monitoring tools available on Bullseye."
return
fi
elif $has_xe; then
driver_info="Modern Intel GPU detected (Xe driver).\nintel-gpu-tools is NOT compatible with Xe.\nOnly nvtop will be offered."
pkg_list=("nvtop")
elif $has_i915; then
+311 -85
View File
@@ -5,9 +5,11 @@ REPO_BACKUP_DIR=""
backup_current_repos() {
REPO_BACKUP_DIR=$(mktemp -d)
for f in /etc/apt/sources.list /etc/apt/sources.list.d/debian.sources; do
for f in /etc/apt/sources.list /etc/apt/sources.list.d/debian.sources \
/etc/apt/sources.list.d/debian-backports.list /etc/apt/sources.list.d/debian-backports.sources; do
if [ -f "$f" ]; then
cp "$f" "$REPO_BACKUP_DIR/$(basename "$f")"
mkdir -p "$REPO_BACKUP_DIR/$(dirname "${f#/etc/apt/}")"
cp "$f" "$REPO_BACKUP_DIR/$(dirname "${f#/etc/apt/}")/$(basename "$f")"
fi
done
}
@@ -17,17 +19,22 @@ restore_previous_repos() {
return
fi
echo -e "${RED}Restoring previous repository configuration...${NC}"
if [ -f "$REPO_BACKUP_DIR/sources.list" ]; then
sudo cp "$REPO_BACKUP_DIR/sources.list" /etc/apt/sources.list
else
sudo rm -f /etc/apt/sources.list
fi
if [ -f "$REPO_BACKUP_DIR/debian.sources" ]; then
sudo cp "$REPO_BACKUP_DIR/debian.sources" /etc/apt/sources.list.d/debian.sources
else
sudo rm -f /etc/apt/sources.list.d/debian.sources
local found=false
for f in /etc/apt/sources.list /etc/apt/sources.list.d/debian.sources \
/etc/apt/sources.list.d/debian-backports.list /etc/apt/sources.list.d/debian-backports.sources; do
local rel="${f#/etc/apt/}"
local backup_file="$REPO_BACKUP_DIR/$rel"
if [ -f "$backup_file" ]; then
sudo cp "$backup_file" "$f"
found=true
elif [ -f "$f" ]; then
sudo rm -f "$f"
found=true
fi
done
if $found; then
sudo rm -f /etc/apt/sources.list.disabled
fi
rm -rf "$REPO_BACKUP_DIR"
REPO_BACKUP_DIR=""
}
@@ -39,40 +46,312 @@ cleanup_repo_backup() {
fi
}
finalize_deb822() {
# ---------------------------------------------------------------------------
# Cleanup helpers for embedded backports
# ---------------------------------------------------------------------------
_clean_embedded_backports_classic() {
local codename="$1"
local file="/etc/apt/sources.list"
[ ! -f "$file" ] && return
grep -qE "^[^#]*${codename}-backports\b" "$file" 2>/dev/null || return
if _confirm "Clean Classic Sources" "Remove backports line from ${file}?"; then
sudo sed -i "/${codename}-backports/d" "$file"
echo "Removed backports from ${file}"
fi
}
_clean_embedded_backports_deb822() {
local codename="$1"
local file="/etc/apt/sources.list.d/debian.sources"
[ ! -f "$file" ] && return
# Only proceed if the Suites line contains the backports token
grep -qE "^Suites:.*${codename}-backports\b" "$file" 2>/dev/null || return
if _confirm "Clean deb822 Sources" "Remove backports suite from ${file}?"; then
# Remove only the backports token, leaving other suites intact
sudo sed -i "s/[[:space:]]*${codename}-backports[[:space:]]*/ /g" "$file"
# Clean up whitespace on Suites lines
sudo sed -i '/^Suites:[[:space:]]*$/d' "$file" 2>/dev/null || true
echo "Removed backports suite from ${file}"
fi
}
# ---------------------------------------------------------------------------
# Write functions idempotent, with _confirm dialogs
# ---------------------------------------------------------------------------
_write_deb822() {
local codename="$1" action="$2" bp_enabled="$3" bp_location="$4"
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+="\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"
if content_differs "$main_file" "$main_content"; then
if _confirm "Deb822 Sources" "Write main deb822 configuration to ${main_file}?"; then
sudo mkdir -p /etc/apt/sources.list.d
echo -e "$main_content" | sudo tee "$main_file" > /dev/null
echo "Wrote ${main_file}"
else
echo "Main repository configuration skipped."
return 1
fi
fi
# Backports: always in separate file
if [ "$bp_enabled" = true ]; then
_write_deb822_backports "$codename"
else
_remove_deb822_backports "$codename"
fi
# On migration from classic, disable the old file
if [ "$action" = "migrate" ] && [ "$bp_location" = "embedded-classic" -o "$bp_location" = "standalone-classic" ]; then
if [ -f /etc/apt/sources.list ]; then
if _confirm "Disable Classic" "Migrating to deb822. Disable /etc/apt/sources.list?"; then
sudo mv /etc/apt/sources.list /etc/apt/sources.list.disabled
echo "Classic sources.list disabled (renamed to sources.list.disabled)"
fi
cleanup_repo_backup
fi
fi
# Clean embedded backports from old classic file if they existed there
if [ "$bp_location" = "embedded-classic" ]; then
_clean_embedded_backports_classic "$codename"
fi
}
_write_deb822_backports() {
local codename="$1"
local bp_file="/etc/apt/sources.list.d/debian-backports.sources"
local bp_content=""
bp_content+="Types: deb\n"
bp_content+="URIs: https://deb.debian.org/debian\n"
bp_content+="Suites: ${codename}-backports\n"
bp_content+="Components: main contrib non-free non-free-firmware\n"
if content_differs "$bp_file" "$bp_content"; then
if _confirm "Deb822 Backports" "Write backports to ${bp_file}?"; then
sudo mkdir -p /etc/apt/sources.list.d
echo -e "$bp_content" | sudo tee "$bp_file" > /dev/null
echo "Wrote ${bp_file}"
fi
fi
# If backports were formerly embedded in debian.sources, clean them
grep -qE "^Suites:.*${codename}-backports\b" /etc/apt/sources.list.d/debian.sources 2>/dev/null && \
_clean_embedded_backports_deb822 "$codename"
}
_remove_deb822_backports() {
local codename="$1"
local bp_file="/etc/apt/sources.list.d/debian-backports.sources"
if [ -f "$bp_file" ]; then
if _confirm "Remove Backports" "Remove ${bp_file}?"; then
sudo rm -f "$bp_file"
echo "Removed ${bp_file}"
fi
fi
# Also clean any embedded backports in main debian.sources
grep -qE "^Suites:.*${codename}-backports\b" /etc/apt/sources.list.d/debian.sources 2>/dev/null && \
_clean_embedded_backports_deb822 "$codename"
# Clean embedded backports from classic file too (safety net)
_clean_embedded_backports_classic "$codename"
}
_write_classic() {
local codename="$1" action="$2" bp_enabled="$3" bp_location="$4"
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+="\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+="\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"
if content_differs "$main_file" "$main_content"; then
if _confirm "Classic Sources" "Write main classic configuration to ${main_file}?"; then
echo -e "$main_content" | sudo tee "$main_file" > /dev/null
echo "Wrote ${main_file}"
else
echo "Main repository configuration skipped."
return 1
fi
fi
# Backports: always in separate file
if [ "$bp_enabled" = true ]; then
_write_classic_backports "$codename"
else
_remove_classic_backports "$codename"
fi
# On migration from deb822, disable the old file
if [ "$action" = "migrate" ]; then
if [ -f /etc/apt/sources.list.d/debian.sources ]; then
if _confirm "Disable Deb822" "Migrating to classic format. Disable /etc/apt/sources.list.d/debian.sources?"; then
sudo mv /etc/apt/sources.list.d/debian.sources /etc/apt/sources.list.d/debian.sources.disabled
echo "Deb822 sources disabled (renamed to debian.sources.disabled)"
fi
fi
fi
# Clean embedded backports from old deb822 file if they existed there
if [ "$bp_location" = "embedded-deb822" ]; then
_clean_embedded_backports_deb822 "$codename"
fi
}
_write_classic_backports() {
local codename="$1"
local bp_file="/etc/apt/sources.list.d/debian-backports.list"
local bp_content=""
bp_content+="# Backports\n"
bp_content+="deb https://deb.debian.org/debian ${codename}-backports main contrib non-free non-free-firmware\n"
if content_differs "$bp_file" "$bp_content"; then
if _confirm "Classic Backports" "Write backports to ${bp_file}?"; then
sudo mkdir -p /etc/apt/sources.list.d
echo -e "$bp_content" | sudo tee "$bp_file" > /dev/null
echo "Wrote ${bp_file}"
fi
fi
# If backports were formerly embedded in sources.list, clean them
grep -qE "^[^#]*${codename}-backports\b" /etc/apt/sources.list 2>/dev/null && \
_clean_embedded_backports_classic "$codename"
}
_remove_classic_backports() {
local codename="$1"
local bp_file="/etc/apt/sources.list.d/debian-backports.list"
if [ -f "$bp_file" ]; then
if _confirm "Remove Backports" "Remove ${bp_file}?"; then
sudo rm -f "$bp_file"
echo "Removed ${bp_file}"
fi
fi
# Also clean any embedded backports in main sources.list
grep -qE "^[^#]*${codename}-backports\b" /etc/apt/sources.list 2>/dev/null && \
_clean_embedded_backports_classic "$codename"
# Clean embedded backports from deb822 file too (safety net)
_clean_embedded_backports_deb822 "$codename"
}
# ---------------------------------------------------------------------------
# Main entry point
# ---------------------------------------------------------------------------
configure_repos() {
echo -e "${YELLOW}Repository configuration...${NC}"
local use_deb822=false
if [ "$DEBIAN_CODENAME" = "trixie" ]; then
if whiptail --title "Repository Format" --defaultno --yesno "Use deb822 format (modern .sources)?" 8 60; then
use_deb822=true
fi
fi
local enable_backports=false
if _confirm "Backports" "Enable backports repository?\n\nProvides newer kernel, drivers, Mesa."; then
enable_backports=true
fi
if [ -z "$DEBIAN_CODENAME" ]; then
echo -e "${RED}Error: Could not detect Debian codename. Aborting.${NC}"
return 1
fi
# Detect current state
local current_format
current_format=$(detect_repo_format)
local bp_status
if detect_backports_status "$DEBIAN_CODENAME"; then
bp_status="enabled"
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)"
# Choose format (only Trixie gets the choice)
local use_deb822=false
if [ "$DEBIAN_CODENAME" = "trixie" ]; then
local default_text="no"
[ "$current_format" = "deb822" ] && default_text="yes"
if whiptail --title "Repository Format" --defaultno --yesno "Use deb822 format (modern .sources)?" 8 60; then
use_deb822=true
fi
elif [ "$current_format" = "deb822" ]; then
use_deb822=true
fi
# Choose backports
local enable_backports=false
if _confirm "Backports" "Enable backports repository?\n\nProvides newer kernel, drivers, Mesa."; then
enable_backports=true
fi
# 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"
else
local action="update"
fi
# 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
backup_current_repos
if $use_deb822; then
generate_deb822_sources "$DEBIAN_CODENAME" "$enable_backports"
_write_deb822 "$DEBIAN_CODENAME" "$action" "$enable_backports" "$bp_location"
else
generate_classic_sources "$DEBIAN_CODENAME" "$enable_backports"
_write_classic "$DEBIAN_CODENAME" "$action" "$enable_backports" "$bp_location"
fi
echo "Updating package lists..."
@@ -83,11 +362,14 @@ configure_repos() {
echo -e "${GREEN}Repositories configured and updated successfully.${NC}"
if $use_deb822; then
finalize_deb822
# Remove any leftover disabled files from old classic format
[ -f /etc/apt/sources.list.disabled ] && sudo rm -f /etc/apt/sources.list.disabled
else
cleanup_repo_backup
[ -f /etc/apt/sources.list.d/debian.sources.disabled ] && sudo rm -f /etc/apt/sources.list.d/debian.sources.disabled
fi
cleanup_repo_backup
local upgradable
upgradable=$(apt list --upgradable 2>/dev/null | grep -c /)
if [ "$upgradable" -gt 0 ]; then
@@ -108,59 +390,3 @@ configure_repos() {
return 1
fi
}
generate_classic_sources() {
local codename="$1"
local backports="$2"
local content=""
content="# Official repository\n"
content+="deb https://deb.debian.org/debian ${codename} main contrib non-free non-free-firmware\n"
content+="# deb-src https://deb.debian.org/debian ${codename} main contrib non-free non-free-firmware\n\n"
content+="# Updates\n"
content+="deb https://deb.debian.org/debian ${codename}-updates main contrib non-free non-free-firmware\n"
content+="# deb-src https://deb.debian.org/debian ${codename}-updates main contrib non-free non-free-firmware\n\n"
content+="# Security\n"
content+="deb https://security.debian.org/debian-security ${codename}-security main contrib non-free non-free-firmware\n"
content+="# deb-src https://security.debian.org/debian-security ${codename}-security main contrib non-free non-free-firmware\n\n"
if $backports; then
content+="# Backports (active)\n"
content+="deb https://deb.debian.org/debian ${codename}-backports main contrib non-free non-free-firmware\n"
content+="# deb-src https://deb.debian.org/debian ${codename}-backports main contrib non-free non-free-firmware\n"
else
content+="# Backports (not enabled)\n"
content+="# deb https://deb.debian.org/debian ${codename}-backports main contrib non-free non-free-firmware\n"
fi
echo -e "$content" | sudo tee /etc/apt/sources.list > /dev/null
}
generate_deb822_sources() {
local codename="$1"
local backports="$2"
sudo mkdir -p /etc/apt/sources.list.d
local content=""
content="Types: deb\n"
content+="URIs: https://deb.debian.org/debian\n"
content+="Suites: ${codename} ${codename}-updates\n"
content+="Components: main contrib non-free non-free-firmware\n\n"
content+="Types: deb\n"
content+="URIs: https://security.debian.org/debian-security\n"
content+="Suites: ${codename}-security\n"
content+="Components: main contrib non-free non-free-firmware\n\n"
if $backports; then
content+="Types: deb\n"
content+="URIs: https://deb.debian.org/debian\n"
content+="Suites: ${codename}-backports\n"
content+="Components: main contrib non-free non-free-firmware\n"
fi
echo -e "$content" | sudo tee /etc/apt/sources.list.d/debian.sources > /dev/null
}
+81
View File
@@ -0,0 +1,81 @@
# shellcheck disable=SC2148
# repo_detect.sh Detection-only helpers for idempotent repository configuration.
# Part A of the two-part architecture. No user dialogs, no writes.
# Detect the format of the main repo file
# Returns: "deb822", "classic", or "none"
detect_repo_format() {
if [ -f /etc/apt/sources.list.d/debian.sources ]; then
echo "deb822"
elif [ -f /etc/apt/sources.list ]; then
echo "classic"
else
echo "none"
fi
}
# Check whether backports are currently enabled (any format)
# Returns: 0 if enabled, 1 otherwise
detect_backports_status() {
local codename="$1"
if [ -f /etc/apt/sources.list.d/debian.sources ]; then
grep -qE "^Suites:.*${codename}-backports" /etc/apt/sources.list.d/debian.sources 2>/dev/null && return 0
fi
if [ -f /etc/apt/sources.list ]; then
grep -qE "^[^#]*${codename}-backports" /etc/apt/sources.list 2>/dev/null && return 0
fi
if [ -f /etc/apt/sources.list.d/debian-backports.sources ]; then
grep -qE "^Suites:.*${codename}-backports" /etc/apt/sources.list.d/debian-backports.sources 2>/dev/null && return 0
fi
if [ -f /etc/apt/sources.list.d/debian-backports.list ]; then
grep -qE "^[^#]*${codename}-backports" /etc/apt/sources.list.d/debian-backports.list 2>/dev/null && return 0
fi
return 1
}
# Locate where backports are configured
# Returns: "standalone-deb822" (debian-backports.sources),
# "standalone-classic" (debian-backports.list),
# "embedded-deb822" (inside debian.sources),
# "embedded-classic" (inside sources.list),
# "none"
detect_backports_location() {
local codename="$1"
if [ -f /etc/apt/sources.list.d/debian-backports.sources ] && \
grep -qE "^Suites:.*${codename}-backports" /etc/apt/sources.list.d/debian-backports.sources 2>/dev/null; then
echo "standalone-deb822"
elif [ -f /etc/apt/sources.list.d/debian-backports.list ] && \
grep -qE "^[^#]*${codename}-backports" /etc/apt/sources.list.d/debian-backports.list 2>/dev/null; then
echo "standalone-classic"
elif [ -f /etc/apt/sources.list.d/debian.sources ] && \
grep -qE "^Suites:.*${codename}-backports" /etc/apt/sources.list.d/debian.sources 2>/dev/null; then
echo "embedded-deb822"
elif [ -f /etc/apt/sources.list ] && \
grep -qE "^[^#]*${codename}-backports" /etc/apt/sources.list 2>/dev/null; then
echo "embedded-classic"
else
echo "none"
fi
}
# Compare generated content vs existing file (idempotency check)
# Returns: 0 if content differs, 1 if identical
content_differs() {
local file="$1"
local content="$2"
if [ ! -f "$file" ]; then
return 0
fi
local current
current=$(cat "$file")
local generated
generated=$(echo -e "$content")
if [ "$current" = "$generated" ]; then
return 1
fi
return 0
}
+145 -16
View File
@@ -1,30 +1,159 @@
#!/usr/bin/env bash
# Adds user to sudo group and optionally enables pwfeedback
# sudo_config.sh — User Privileges & Feedback submenu
# License GPL v3
config_sudo() {
echo -e "${YELLOW}Configuring sudo...${NC}"
echo -e "${YELLOW}User Privileges & Feedback${NC}"
while true; do
local choice
choice=$(whiptail --title "User Privileges & Feedback" --menu \
"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)
[ -z "$choice" ] && return
clear
case "$choice" in
1) _check_sudo_group ;;
2) _configure_nopasswd ;;
3) _repair_home_ownership ;;
4) _toggle_pwfeedback ;;
5) return ;;
esac
done
}
# ── Option 1: Sudo Group Membership ──
_check_sudo_group() {
if groups "$USER" | grep -qE '\bsudo\b'; then
echo "User is already in the sudo group."
_msg "Sudo Group" "User '$USER' is already in the sudo group."
else
echo "Adding user '$USER' to sudo group..."
if _confirm "Sudo Group" \
"User '$USER' is NOT in the sudo group.\n\nAdd to sudo group?"; then
if sudo usermod -aG sudo "$USER"; then
echo -e "${GREEN}Done. Note: you need to log out and back in for group changes to take effect.${NC}"
_msg "Sudo Group" \
"User added to sudo group.\n\nLog out and back in for\ngroup changes to take effect." 10 60
else
echo -e "${RED}Failed to add user to sudo group.${NC}"
_msg "Sudo Group" "Failed to add user to sudo group." 7 60
return 1
fi
fi
fi
}
# ── Option 2: Passwordless Sudo (NOPASSWD) ──
_configure_nopasswd() {
local nopasswd_file="/etc/sudoers.d/${USER}-nopasswd"
if [ -f "$nopasswd_file" ]; then
if _confirm "NOPASSWD" \
"Passwordless sudo is already configured.\n\nRemove it to restore password prompts?"; then
sudo rm -f "$nopasswd_file"
echo -e "${GREEN}Passwordless sudo removed.${NC}"
fi
return
fi
if _confirm "NOPASSWD" \
"Configure passwordless sudo for maintenance commands?\n\n\
- apt / apt-get (package management)\n\
- systemctl (service management)\n\
- shutdown / reboot / halt (power commands)\n\n\
Useful for automation but reduces security." 14 70; then
local choices
choices=$(whiptail --title "NOPASSWD Commands" --checklist \
"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)
clear
[ -z "$choices" ] && { echo "No commands selected."; return; }
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
local content=""
for cmd in $cleaned; do
case $cmd in
apt)
content+="${USER} ALL=(root) NOPASSWD: /usr/bin/apt, /usr/bin/apt-get, /bin/apt, /bin/apt-get\n"
;;
systemctl)
content+="${USER} ALL=(root) NOPASSWD: /usr/bin/systemctl, /bin/systemctl\n"
;;
power)
content+="${USER} ALL=(root) NOPASSWD: /usr/sbin/shutdown, /sbin/shutdown, /usr/sbin/reboot, /sbin/reboot, /usr/sbin/halt, /sbin/halt\n"
;;
esac
done
echo -e "$content" | sudo tee "$nopasswd_file" > /dev/null
sudo chmod 0440 "$nopasswd_file"
if [ -f "$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
}
# ── Option 3: Repair Home Directory Ownership ──
_repair_home_ownership() {
local home
home=$(eval echo "~$USER")
if [ ! -d "$home" ]; then
_msg "Home Directory" "Home directory '$home' does not exist." 8 60
return 1
fi
local uid uid_owner
uid=$(id -u "$USER" 2>/dev/null)
uid_owner=$(stat -c '%u' "$home" 2>/dev/null || echo "0")
if [ "$uid_owner" != "$uid" ]; then
local expected_user
expected_user=$(id -nu "$uid_owner" 2>/dev/null || echo "UID $uid_owner")
if _confirm "Home Permissions" \
"Home directory '$home' is owned by\n'$expected_user' (expected: '$USER').\n\nRepair ownership?" 12 65; then
if sudo chown -R "$USER:$USER" "$home"; then
echo -e "${GREEN}Home directory ownership repaired.${NC}"
else
echo -e "${RED}Failed to repair home directory ownership.${NC}"
return 1
fi
fi
else
_msg "Home Permissions" "Home directory ownership is correct\n(owner: $USER)." 8 60
fi
}
# ── Option 4: Sudo Password Feedback (pwfeedback) ──
_toggle_pwfeedback() {
local fb_file="/etc/sudoers.d/pwfeedback"
if [ -f "$fb_file" ]; then
if _confirm "Password Feedback" \
"Asterisks are currently ENABLED when typing sudo password.\n\nDisable them?"; then
sudo rm -f "$fb_file"
echo -e "${GREEN}Password feedback disabled.${NC}"
fi
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
echo -e "${GREEN}Password feedback enabled.${NC}"
else
echo -e "${RED}Failed to create $fb_file${NC}"
return 1
fi
fi
if _confirm "Sudo Password Feedback" "Show asterisks when typing the sudo password?"; then
echo 'Defaults pwfeedback' | sudo tee /etc/sudoers.d/pwfeedback > /dev/null
if [ $? -eq 0 ]; then
echo -e "${GREEN}Password feedback enabled.${NC}"
else
echo -e "${RED}Failed to create /etc/sudoers.d/pwfeedback.${NC}"
fi
else
echo "Skipping password feedback setting."
fi
}