diff --git a/README.md b/README.md index a3e618e..4be83c0 100644 --- a/README.md +++ b/README.md @@ -1781,7 +1781,66 @@ einmal sichtbar. Das gilt für **alle** Fenster, auch in `migrate_creator.sh`: sämtliche Dialoge laufen über drei gemeinsame Stellen in [scripts/lib/common.sh](scripts/lib/common.sh), die die Größe selbst berechnen. -### 14.4 Selbstprüfung +### 14.4 Rahmen erscheinen als `q`, `x`, `l`, `m` (PuTTY) + +Sieht die Oberfläche so aus – + +``` +lqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqk +x Projekt : /opt/checkmk-stack x +``` + +– dann fehlt auf dem Server eine **UTF-8-Locale**. Ohne sie zeichnen +`dialog` und `whiptail` die Rahmen über die alte VT100-Umschaltung `ESC(0`. +Terminals im UTF-8-Modus – PuTTY in der Vorgabe – ignorieren diese Umschaltung +und zeigen stattdessen die rohen Buchstaben. + +Nachgemessen: bei `LC_ALL=C` schickt `whiptail` eine `ESC(0`-Umschaltung und +**91 rohe `q`**; mit UTF-8-Locale keine einzige. + +**Das Skript behebt das selbst.** Beim Start der Oberfläche setzt es +`LC_CTYPE` auf die erste verfügbare UTF-8-Locale (`C.UTF-8`, `en_US.UTF-8`, …). +Nur `LC_CTYPE`, damit Sortierung und Zahlenformat unberührt bleiben. Ist +`LC_ALL` auf einen Nicht-UTF-8-Wert gesetzt, wird es dabei entfernt – sonst +würde es `LC_CTYPE` aushebeln. Prüfen lässt sich das mit: + +```bash +./scripts/cmk-manage.sh selftest # Abschnitt "Zeichensatz fuer die Oberflaeche" +``` + +Meldet die Prüfung, dass **keine** UTF-8-Locale vorhanden ist, fehlt das +Sprachpaket: + +```bash +sudo dnf install -y glibc-langpack-en # RHEL/Rocky/Alma +sudo apt-get install -y locales # Debian/Ubuntu +``` + +#### Einstellungen in PuTTY + +Damit es auch auf der Gegenseite passt: + +| PuTTY-Bereich | Einstellung | +|---|---| +| Window → Translation | **Remote character set: UTF-8** | +| Window → Translation | Handling of line drawing characters: **Use Unicode line drawing code points** | +| Connection → Data | Terminal-type string: **`xterm-256color`** (Vorgabe ist nur `xterm`) | +| Window → Appearance | eine Schrift mit Rahmenzeichen, z. B. *Consolas* oder *DejaVu Sans Mono* | + +Wer die Sitzung dauerhaft so haben möchte, speichert sie in PuTTY unter +*Session → Saved Sessions*. + +> Hilft beides nicht – etwa weil auf dem Server keine UTF-8-Locale +> installiert werden darf – lässt sich die Oberfläche mit einfachen +> ASCII-Rahmen zeichnen: +> +> ```bash +> CMK_TUI_ASCII=1 ./scripts/cmk-manage.sh gui +> ``` +> +> Das wirkt allerdings nur mit `dialog`; `whiptail` kennt keine solche Option. + +### 14.5 Selbstprüfung ```bash ./scripts/cmk-manage.sh selftest diff --git a/README_en.md b/README_en.md index 183cc6e..1c60cac 100644 --- a/README_en.md +++ b/README_en.md @@ -1782,7 +1782,64 @@ through three shared entry points in [scripts/lib/common.sh](scripts/lib/common.sh) which compute the size themselves. -### 14.4 Self-check +### 14.4 Borders show up as `q`, `x`, `l`, `m` (PuTTY) + +If the interface looks like this – + +``` +lqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqk +x Projekt : /opt/checkmk-stack x +``` + +– then the server lacks a **UTF-8 locale**. Without one, `dialog` and +`whiptail` draw the borders through the old VT100 switch `ESC(0`. Terminals in +UTF-8 mode – PuTTY by default – ignore that switch and show the raw letters +instead. + +Measured: with `LC_ALL=C`, `whiptail` emits one `ESC(0` switch and **91 raw +`q`** characters; with a UTF-8 locale, none at all. + +**The script fixes this itself.** When starting the interface it sets +`LC_CTYPE` to the first available UTF-8 locale (`C.UTF-8`, `en_US.UTF-8`, …) – +only `LC_CTYPE`, so sorting and number formats stay untouched. If `LC_ALL` is +set to a non-UTF-8 value it is removed, since it would otherwise override +`LC_CTYPE`. Verify with: + +```bash +./scripts/cmk-manage.sh selftest # section "Zeichensatz fuer die Oberflaeche" +``` + +If the check reports that **no** UTF-8 locale exists, the language pack is +missing: + +```bash +sudo dnf install -y glibc-langpack-en # RHEL/Rocky/Alma +sudo apt-get install -y locales # Debian/Ubuntu +``` + +#### PuTTY settings + +So that the other end matches: + +| PuTTY section | Setting | +|---|---| +| Window → Translation | **Remote character set: UTF-8** | +| Window → Translation | Handling of line drawing characters: **Use Unicode line drawing code points** | +| Connection → Data | Terminal-type string: **`xterm-256color`** (the default is just `xterm`) | +| Window → Appearance | a font with box-drawing glyphs, e.g. *Consolas* or *DejaVu Sans Mono* | + +Save the session under *Session → Saved Sessions* to keep these settings. + +> If neither helps – for instance because no UTF-8 locale may be installed on +> the server – the interface can be drawn with plain ASCII borders: +> +> ```bash +> CMK_TUI_ASCII=1 ./scripts/cmk-manage.sh gui +> ``` +> +> This only works with `dialog`; `whiptail` has no such option. + +### 14.5 Self-check ```bash ./scripts/cmk-manage.sh selftest diff --git a/scripts/cmk-manage.sh b/scripts/cmk-manage.sh index 9a720d8..7082999 100755 --- a/scripts/cmk-manage.sh +++ b/scripts/cmk-manage.sh @@ -4750,7 +4750,20 @@ cmd_selftest() { printf ' "set -e" das Skript. Besser als if-Block schreiben.\n' fi - printf '\n%s5. Einstellungstabelle%s\n' "$C_BLD" "$C_RST" + printf '\n%s5. Zeichensatz fuer die Oberflaeche%s\n' "$C_BLD" "$C_RST" + local before="${LC_ALL:-${LC_CTYPE:-${LANG:-}}}" + ui_fix_locale || true + printf ' Locale vorher : %s\n' "$before" + printf ' Locale jetzt : %s\n' "${LC_CTYPE:-${LANG:-}}" + if [ -n "${UI_ASCII:-}" ]; then + printf ' %s[ WARN ]%s Keine UTF-8-Locale vorhanden - die Rahmen werden einfach gezeichnet.\n' "$C_YEL" "$C_RST" + printf ' Abhilfe: dnf install -y glibc-langpack-en bzw. locale-gen\n' + else + printf ' %s[ OK ]%s UTF-8 - die Rahmen werden sauber gezeichnet%s\n' "$C_GRN" "$C_RST" \ + "$([ -n "${UI_LOCALE_NOTE:-}" ] && echo " (${UI_LOCALE_NOTE})")" + fi + + printf '\n%s6. Einstellungstabelle%s\n' "$C_BLD" "$C_RST" n="$(settings_defs | awk -F'|' 'NF!=6' | wc -l)" if [ "$n" -eq 0 ]; then printf ' %s[ OK ]%s alle Zeilen haben sechs Felder\n' "$C_GRN" "$C_RST" diff --git a/scripts/lib/common.sh b/scripts/lib/common.sh index fc6b61f..7550cc7 100644 --- a/scripts/lib/common.sh +++ b/scripts/lib/common.sh @@ -297,7 +297,57 @@ ui_calc_text() { # text zusatzzeilen return 0 } +# --------------------------------------------------------------------- +# Rahmenzeichen in PuTTY & Co. +# +# Ohne UTF-8-Locale zeichnen dialog/whiptail die Rahmen ueber die alte +# VT100-Umschaltung "ESC(0". Terminals, die im UTF-8-Modus laufen - +# PuTTY in der Vorgabe -, ignorieren diese Umschaltung und zeigen +# stattdessen die rohen Buchstaben q, x, l, m. +# +# Nachgemessen: bei LC_ALL=C schickt whiptail eine ESC(0-Umschaltung und +# 91 rohe "q"; mit UTF-8-Locale keine einzige. Es genuegt, LC_CTYPE zu +# setzen - Sortierung und Zahlenformat bleiben damit unberuehrt. +ui_fix_locale() { + [ -n "${UI_LOCALE_DONE:-}" ] && return 0 + UI_LOCALE_DONE=1 + UI_LOCALE_NOTE="" + case "${LC_ALL:-${LC_CTYPE:-${LANG:-}}}" in + *UTF-8*|*utf-8*|*UTF8*|*utf8*) return 0 ;; + esac + local l + for l in C.UTF-8 C.utf8 en_US.UTF-8 en_US.utf8 de_DE.UTF-8 de_DE.utf8; do + if locale -a 2>/dev/null | grep -qix "$l"; then + # LC_ALL sticht jede einzelne Kategorie aus - solange es auf + # einem Nicht-UTF-8-Wert steht, bliebe LC_CTYPE wirkungslos. + if [ -n "${LC_ALL:-}" ]; then unset LC_ALL; fi + export LC_CTYPE="$l" + UI_LOCALE_NOTE="LC_CTYPE auf $l gesetzt (war nicht UTF-8)" + return 0 + fi + done + # Keine UTF-8-Locale vorhanden - dann bleibt nur ASCII + UI_ASCII=1 + UI_LOCALE_NOTE="keine UTF-8-Locale gefunden - einfache Rahmen" + return 1 +} + +# Zusaetzliche Argumente, wenn nur ASCII-Rahmen moeglich sind +ui_ascii_args() { + UI_EXTRA=() + case "${CMK_TUI_ASCII:-}${UI_ASCII:-}" in + '') return 0 ;; + esac + # Nur dialog kann das; whiptail kennt die Option nicht. + if [ "${UI_BIN:-}" = dialog ] && dialog --ascii-lines --print-version >/dev/null 2>&1; then + UI_EXTRA=(--ascii-lines) + fi + return 0 +} + ui_init() { + ui_fix_locale || true + ui_ascii_args # Geometrie IMMER setzen - sonst laeuft das Skript unter "set -u" auf # eine unbound variable, wenn UI_BIN von aussen vorgegeben wurde. UI_H="${UI_H:-22}"; UI_W="${UI_W:-78}"; UI_MH="${UI_MH:-13}" @@ -335,7 +385,7 @@ _ui_list() { ui_init local widget="$1" title="$2" text="$3" per="$4"; shift 4 ui_calc "$text" "$per" "$@" - "$UI_BIN" --backtitle "$UI_BACKTITLE" --title "$title" \ + "$UI_BIN" ${UI_EXTRA[@]+"${UI_EXTRA[@]}"} --backtitle "$UI_BACKTITLE" --title "$title" \ "$widget" "$text" "$UI_H" "$UI_W" "$UI_MH" "$@" 3>&1 1>&2 2>&3 } @@ -347,10 +397,10 @@ _ui_box() { ui_calc_text "$text" "$extra" case "$widget" in --inputbox|--passwordbox) - "$UI_BIN" --backtitle "$UI_BACKTITLE" --title "$title" \ + "$UI_BIN" ${UI_EXTRA[@]+"${UI_EXTRA[@]}"} --backtitle "$UI_BACKTITLE" --title "$title" \ "$widget" "$text" "$UI_H" "$UI_W" "$@" 3>&1 1>&2 2>&3 ;; *) - "$UI_BIN" --backtitle "$UI_BACKTITLE" --title "$title" \ + "$UI_BIN" ${UI_EXTRA[@]+"${UI_EXTRA[@]}"} --backtitle "$UI_BACKTITLE" --title "$title" \ "$widget" "$text" "$UI_H" "$UI_W" "$@" ;; esac } @@ -359,7 +409,7 @@ _ui_box() { _ui_file() { ui_init ui_term_size - "$UI_BIN" --backtitle "$UI_BACKTITLE" --title "$1" \ + "$UI_BIN" ${UI_EXTRA[@]+"${UI_EXTRA[@]}"} --backtitle "$UI_BACKTITLE" --title "$1" \ --textbox "$2" $(( UI_ROWS - 2 )) $(( UI_COLS - 4 )) }