imagestack/tools/pxe_utils/files/change_language.sh
2026-01-28 09:21:36 +01:00

130 lines
4 KiB
Bash

#!/usr/bin/env bash
# change-system-language-with-zenity.sh
# GUI (Zenity) to set system language on Debian (Cinnamon) from a restricted list.
# Run from a graphical session with sudo:
# sudo -E bash change-system-language-with-zenity.sh
set -euo pipefail
log() { printf "[*] %s\n" "$*"; }
# 0) Must be root
if [[ $EUID -ne 0 ]]; then
echo "Please run as root (e.g., sudo -E bash $0)."
exit 1
fi
# 0.1) Require a GUI session
if [[ -z "${DISPLAY:-}" ]]; then
echo "No DISPLAY detected. Run this from a graphical session."
exit 1
fi
# 1) Ensure zenity + locales
if ! command -v zenity >/dev/null 2>&1; then
log "Installing 'zenity'…"
apt-get update -y
DEBIAN_FRONTEND=noninteractive apt-get install -y zenity
fi
if ! dpkg -s locales >/dev/null 2>&1; then
log "Installing 'locales'…"
apt-get update -y
DEBIAN_FRONTEND=noninteractive apt-get install -y locales
fi
SUPPORTED_FILE="/usr/share/i18n/SUPPORTED"
if [[ ! -f "$SUPPORTED_FILE" ]]; then
zenity --error --title="Locale List Missing" \
--text="Cannot find $SUPPORTED_FILE. Aborting."
exit 1
fi
# 2) Restrict choices to ONLY these locales
# (Adjust here if you want different variants.)
REQUESTED_LOCALES=(
"en_US.UTF-8" # English (United States)
"fa_IR.UTF-8" # Persian (Iran)
"ar_SA.UTF-8" # Arabic (Saudi Arabia)
"uk_UA.UTF-8" # Ukrainian (Ukraine)
"de_DE.UTF-8" # German (Germany)
"fr_FR.UTF-8"
)
# Keep only those actually listed in SUPPORTED (prevents locale-gen errors)
mapfile -t AVAILABLE_LOCALES < <(
grep -E '^\S+\s+UTF-8' "$SUPPORTED_FILE" \
| awk '{print $1}' \
| grep -Fx -f <(printf "%s\n" "${REQUESTED_LOCALES[@]}") \
| sort -u
)
if (( ${#AVAILABLE_LOCALES[@]} == 0 )); then
zenity --error --title="No Locales Available" \
--text="None of the requested locales are available on this system."
exit 1
fi
# Friendly labels
friendly_label() {
case "$1" in
en_US.UTF-8) echo "English (United States) — en_US.UTF-8";;
fr_FR.UTF-8) echo "French (France) - fr_FR.UTF-8";;
fa_IR.UTF-8) echo "Persian (Farsi, Iran) — fa_IR.UTF-8";;
ar_SA.UTF-8) echo "Arabic (Saudi Arabia) — ar_SA.UTF-8";;
uk_UA.UTF-8) echo "Ukrainian (Ukraine) — uk_UA.UTF-8";;
de_DE.UTF-8) echo "German (Germany) — de_DE.UTF-8";;
*) echo "$1";;
esac
}
# 3) Build Zenity radiolist (default en_US if present else first)
ZENITY_ARGS=()
DEFAULT="en_US.UTF-8"
for loc in "${AVAILABLE_LOCALES[@]}"; do
selected="FALSE"
[[ "$loc" == "$DEFAULT" ]] && selected="TRUE"
ZENITY_ARGS+=("$selected" "$loc" "$(friendly_label "$loc")")
done
if ! printf '%s\n' "${AVAILABLE_LOCALES[@]}" | grep -q '^en_US\.UTF-8$'; then
ZENITY_ARGS[0]="TRUE"
fi
CHOICE="$(zenity --list \
--radiolist \
--title="Choose System Language" \
--width=700 --height=420 \
--column="Select" --column="Locale" --column="Description" \
"${ZENITY_ARGS[@]}")" || true
[[ -z "${CHOICE:-}" ]] && exit 0 # user cancelled
TARGET_LOCALE="$CHOICE"
TARGET_LANG_LINE="${TARGET_LOCALE} UTF-8"
zenity --question \
--title="Confirm Language Change" \
--text="Set the system language to:\n\n<b>${TARGET_LOCALE}</b>\n\nThis updates /etc/locale.gen, runs locale-gen, and sets defaults via update-locale.\nLog out or reboot for Cinnamon to fully apply it." \
--no-wrap \
--ok-label="Apply" --cancel-label="Cancel" || exit 0
# Generate
if ! locale-gen 2> >(tee /tmp/locale-gen.err >&2); then
zenity --error --title="locale-gen failed" \
--text="locale-gen encountered an error.\n\nSee /tmp/locale-gen.err for details."
exit 1
fi
# Set system defaults
update-locale LANG="${TARGET_LOCALE}" LANGUAGE="${TARGET_LOCALE%%.*}:en"
# Mirror LANG in /etc/environment
if grep -q '^LANG=' /etc/environment 2>/dev/null; then
sed -i "s/^LANG=.*/LANG=${TARGET_LOCALE}/" /etc/environment
else
echo "LANG=${TARGET_LOCALE}" >> /etc/environment
fi
zenity --info --title="Language Updated" \
--text="System default language set to:\n\n<b>${TARGET_LOCALE}</b>\n\nLog out and back in (or reboot) for Cinnamon to apply it to your desktop session." \
--no-wrap