#!/usr/bin/env bash # Kalina CI — Shell-Prompt und Terminal-Palette installieren. # # Einmal auf einer neuen Maschine ausfuehren, danach ist die Shell im Kalina-CI # (Tinte #0B0F14, Knochenweiss #F5F5EF, Markenrot #C1121F als Grafik-Akzent). # # ./install.sh # alles, was erkannt wird # ./install.sh --dry-run # nur zeigen, was passieren wuerde # ./install.sh --shell-only # nur zsh + Prompt # ./install.sh --terminal-only # nur Terminal-Palette # ./install.sh --no-chsh # Login-Shell nicht anfassen # # Grundsaetze: jede Datei wird vorher gesichert (.vor-kalina-ci-), # jeder Block ist an einem Marker erkennbar und wird nicht doppelt geschrieben, # jede veraenderte Datei wird anschliessend mit dem passenden Pruefer getestet. set -uo pipefail MARK_ON="# >>> kalina-ci >>>" MARK_OFF="# <<< kalina-ci <<<" TS="$(date +%Y%m%d-%H%M%S)" CONF_DIR="$HOME/.config/kalina-ci" PROMPT="$CONF_DIR/prompt.zsh" SRC_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" DRY=0; DO_SHELL=1; DO_TERM=1; DO_CHSH=1 for arg in "$@"; do case "$arg" in --dry-run) DRY=1 ;; --shell-only) DO_TERM=0 ;; --terminal-only) DO_SHELL=0 ;; --no-chsh) DO_CHSH=0 ;; -h|--help) sed -n '2,18p' "$0"; exit 0 ;; *) echo "unbekannte Option: $arg" >&2; exit 2 ;; esac done say() { printf '%s\n' "$*"; } step() { printf '\n\033[38;2;224;69;79m▸\033[0m %s\n' "$*"; } ok() { printf ' \033[38;2;127;168;140m✓\033[0m %s\n' "$*"; } warn() { printf ' \033[38;2;199;164;107m!\033[0m %s\n' "$*"; } run() { if [ "$DRY" = 1 ]; then printf ' [dry] %s\n' "$*"; else "$@"; fi } backup() { [ -e "$1" ] || return 0 local dst="$1.vor-kalina-ci-$TS" run cp -a "$1" "$dst" ok "Sicherung: $dst" } # ----------------------------------------------------------------- Hilfsmittel SUDO="" if [ "$(id -u)" = 0 ]; then SUDO="" elif command -v sudo >/dev/null && sudo -n true 2>/dev/null; then SUDO="sudo -n" fi install_zsh() { command -v zsh >/dev/null && { ok "zsh vorhanden: $(zsh --version)"; return 0; } local pm="" for c in apt-get dnf pacman zypper apk; do command -v "$c" >/dev/null && pm="$c" && break; done [ -n "$pm" ] || { warn "kein bekannter Paketmanager — zsh bitte von Hand installieren"; return 1; } if [ -z "$SUDO" ] && [ "$(id -u)" != 0 ]; then warn "zsh fehlt und sudo verlangt ein Passwort. Bitte selbst ausfuehren:" case "$pm" in apt-get) say " sudo apt-get install -y zsh" ;; dnf) say " sudo dnf install -y zsh" ;; pacman) say " sudo pacman -S --needed zsh" ;; zypper) say " sudo zypper install -y zsh" ;; apk) say " sudo apk add zsh" ;; esac return 1 fi case "$pm" in apt-get) run $SUDO env DEBIAN_FRONTEND=noninteractive apt-get install -y zsh ;; dnf) run $SUDO dnf install -y zsh ;; pacman) run $SUDO pacman -S --needed --noconfirm zsh ;; zypper) run $SUDO zypper --non-interactive install zsh ;; apk) run $SUDO apk add zsh ;; esac command -v zsh >/dev/null && ok "zsh installiert: $(zsh --version)" || warn "zsh weiterhin nicht auffindbar" } # Block mit Markern an eine Datei anhaengen (nicht doppelt) append_block() { local file="$1" if [ -f "$file" ] && grep -qF "$MARK_ON" "$file"; then ok "$(basename "$file"): Kalina-CI-Block ist schon drin" return 0 fi backup "$file" if [ "$DRY" = 1 ]; then printf ' [dry] Block an %s anhaengen\n' "$file" else { printf '\n%s\n' "$MARK_ON"; cat; printf '%s\n' "$MARK_OFF"; } >> "$file" fi ok "$(basename "$file"): Block angehaengt" } # ------------------------------------------------------------------ Shell do_shell() { step "Shell (zsh + Kalina-CI-Prompt)" install_zsh || true run mkdir -p "$CONF_DIR" if [ -f "$PROMPT" ] && [ -f "$SRC_DIR/prompt.zsh" ]; then backup "$PROMPT" run cp -f "$SRC_DIR/prompt.zsh" "$PROMPT" ok "prompt.zsh aus $SRC_DIR uebernommen" elif [ -f "$SRC_DIR/prompt.zsh" ]; then run cp -f "$SRC_DIR/prompt.zsh" "$PROMPT" ok "prompt.zsh installiert" elif [ -f "$PROMPT" ]; then ok "prompt.zsh liegt bereits in $CONF_DIR" else warn "prompt.zsh weder neben dem Skript noch in $CONF_DIR — Shell-Teil uebersprungen" return 1 fi local zshrc="$HOME/.zshrc" if [ ! -f "$zshrc" ]; then backup "$zshrc" if [ "$DRY" = 0 ]; then cat > "$zshrc" <<'RC' # Grundgeruest (angelegt von install.sh aus mm/kalina-ci) HISTFILE=~/.zsh_history HISTSIZE=20000 SAVEHIST=20000 setopt append_history share_history hist_ignore_dups hist_ignore_space extended_history setopt autocd interactive_comments unsetopt beep autoload -Uz compinit && compinit -u -d "$HOME/.zcompdump" zstyle ':completion:*' menu select bindkey -e RC fi ok "~/.zshrc angelegt" fi printf '\n[[ -r ~/.config/kalina-ci/prompt.zsh ]] && source ~/.config/kalina-ci/prompt.zsh\n' \ | append_block "$zshrc" # Nicht-interaktive Aufrufe (ssh host '...') erwarten bash-Verhalten local zshenv="$HOME/.zshenv" if ! grep -qs "kalina-ci" "$zshenv"; then backup "$zshenv" if [ "$DRY" = 0 ]; then { printf '%s\n' "$MARK_ON" printf '# Leerer Glob soll nicht abbrechen (bash-Verhalten fuer Automatik/Remote).\n' printf 'if ! [[ -o interactive ]]; then setopt no_nomatch 2>/dev/null; fi\n' printf '%s\n' "$MARK_OFF" } >> "$zshenv" fi ok "~/.zshenv: no_nomatch fuer nicht-interaktive Shells" else ok "~/.zshenv: schon eingerichtet" fi if [ "$DRY" = 0 ]; then zsh -n "$zshrc" && ok "zsh -n ~/.zshrc" || warn "~/.zshrc hat einen Syntaxfehler" zsh -n "$PROMPT" && ok "zsh -n prompt.zsh" || warn "prompt.zsh hat einen Syntaxfehler" fi # Login-Shell local cur; cur="$(getent passwd "$(id -un)" | cut -d: -f7)" if [ "$cur" = "$(command -v zsh 2>/dev/null)" ]; then ok "Login-Shell ist bereits zsh" elif [ "$DO_CHSH" = 0 ]; then warn "Login-Shell bleibt $cur (--no-chsh); Start mit 'exec zsh' oder 'chsh -s $(command -v zsh)'" else run $SUDO chsh -s "$(command -v zsh)" "$(id -un)" && ok "Login-Shell auf zsh gestellt (greift beim naechsten Login)" fi } # --------------------------------------------------------------- Terminal do_terminal() { step "Terminal-Palette" local chosen="" if command -v foot >/dev/null; then chosen=foot; foot_setup elif command -v qterminal >/dev/null; then chosen=qterminal; qterminal_setup elif command -v xfce4-terminal >/dev/null; then chosen=xfce4-terminal; xfce_setup fi # xterm-Ressourcen zusaetzlich, wenn xterm daneben installiert ist. if command -v xterm >/dev/null && [ "$chosen" != xterm ]; then chosen="${chosen:-xterm}"; xterm_setup fi [ -n "$chosen" ] || warn "kein bekanntes Terminal gefunden (foot, qterminal, xfce4-terminal, xterm)" } foot_setup() { local cfg="$HOME/.config/foot" run mkdir -p "$cfg" if [ -f "$cfg/foot.ini" ] && grep -qF "Kalina CI" "$cfg/foot.ini"; then ok "foot: CI-Palette ist schon drin" else backup "$cfg/foot.ini" if [ "$DRY" = 0 ]; then cat >> "$cfg/foot.ini" <<'FOOT' # --- Kalina CI ------------------------------------------------------------- # Absichtlich NACH einem eventuellen include: in foot gewinnt die spaetere # Angabe, damit die CI-Palette jedes Theme-Update ueberlebt. [colors-dark] background=0b0f14 foreground=f5f5ef regular0=1a212a regular1=e0454f regular2=7fa88c regular3=c7a46b regular4=7e93ad regular5=be8fa0 regular6=8fb3b3 regular7=f5f5ef bright0=5c6675 bright1=ff6b75 bright2=9cc2a8 bright3=e0c08a bright4=a3b6cb bright5=d3a8b8 bright6=aecbcb bright7=ffffff selection-foreground=0b0f14 selection-background=f5f5ef cursor=0b0f14 c1121f # --- Ende Kalina CI -------------------------------------------------------- FOOT fi ok "foot: [colors-dark] angehaengt" fi if command -v foot >/dev/null && [ "$DRY" = 0 ]; then foot --check-config 2>&1 | grep -v "UTF-8 locale" | grep . && warn "foot meldet Konfigurationsfehler (siehe oben)" \ || ok "foot --check-config: keine Fehler" fi } qterminal_setup() { local share="$HOME/.local/share/qterminal-ci/qtermwidget6/color-schemes" local ini="$HOME/.config/qterminal.org/qterminal.ini" run mkdir -p "$share" "$(dirname "$ini")" if [ "$DRY" = 0 ]; then cat > "$share/KalinaCI.colorscheme" <<'SCHEME' [Color0] Color=26,33,42 [Color0Intense] Color=92,102,117 [Color0Faint] Color=20,26,34 [Color1] Color=224,69,79 [Color1Intense] Color=255,107,117 [Color1Faint] Color=146,50,57 [Color2] Color=127,168,140 [Color2Intense] Color=156,194,168 [Color2Faint] Color=84,110,91 [Color3] Color=199,164,107 [Color3Intense] Color=224,192,138 [Color3Faint] Color=128,107,74 [Color4] Color=126,147,173 [Color4Intense] Color=163,182,203 [Color4Faint] Color=85,97,113 [Color5] Color=190,143,160 [Color5Intense] Color=211,168,184 [Color5Faint] Color=122,95,105 [Color6] Color=143,179,179 [Color6Intense] Color=174,203,203 [Color6Faint] Color=94,116,116 [Color7] Color=245,245,239 [Color7Intense] Color=255,255,255 [Color7Faint] Color=155,155,152 [Background] Color=11,15,20 [BackgroundIntense] Color=26,33,42 [BackgroundFaint] Color=11,15,20 [Foreground] Color=245,245,239 [ForegroundIntense] Color=255,255,255 [ForegroundFaint] Color=138,148,162 [General] Description=Kalina CI Opacity=1 SCHEME ok "qterminal: Farbschema geschrieben" fi backup "$ini" if [ "$DRY" = 0 ]; then mkdir -p "$(dirname "$ini")"; touch "$ini" if ! grep -q '^\[General\]' "$ini"; then printf '[General]\n' | cat - "$ini" > "$ini.neu" && mv "$ini.neu" "$ini"; fi set_ini() { # set_ini if grep -qE "^$1=" "$ini"; then sed -i "s|^$1=.*|$1=$2|" "$ini" else sed -i "/^\[General\]/a $1=$2" "$ini" fi } set_ini colorScheme KalinaCI set_ini fontFamily "DejaVu Sans Mono" set_ini fontSize 11 set_ini TerminalTransparency 0 fi ok "qterminal: colorScheme/font/TerminalTransparency gesetzt" # qtermwidget6 durchsucht XDG_DATA_DIRS — eigenen Pfad dort einhaengen local envd="$HOME/.config/environment.d" run mkdir -p "$envd" if [ "$DRY" = 0 ]; then cat > "$envd/60-kalina-ci-terminal.conf" <<'ENVD' # Kalina CI: Farbschema fuer QTerminal/QTermWidget (ohne sudo) XDG_DATA_DIRS=${HOME}/.local/share/qterminal-ci:${XDG_DATA_DIRS:-/usr/local/share:/usr/share} ENVD fi ok "environment.d/60-kalina-ci-terminal.conf (greift nach dem naechsten Login)" } xfce_setup() { local dir="$HOME/.config/xfce4/terminal" rc rc="$dir/terminalrc" run mkdir -p "$dir" backup "$rc" if [ "$DRY" = 0 ]; then cat > "$rc" <<'XFCE' [Configuration] FontName=DejaVu Sans Mono 11 MiscAlwaysShowTabs=FALSE MiscBell=FALSE MiscCursorBlinks=FALSE MiscCursorShape=TERMINAL_CURSOR_SHAPE_BLOCK MiscShowUnsafePasteDialog=FALSE ColorForeground=#f5f5ef ColorBackground=#0b0f14 ColorCursor=#c1121f ColorCursorUseDefault=FALSE ColorPalette=#1a212a;#e0454f;#7fa88c;#c7a46b;#7e93ad;#be8fa0;#8fb3b3;#f5f5ef;#5c6675;#ff6b75;#9cc2a8;#e0c08a;#a3b6cb;#d3a8b8;#aecbcb;#ffffff ColorUseTheme=false BoldIsBright=TRUE BackgroundMode=TERMINAL_BACKGROUND_SOLID XFCE fi ok "xfce4-terminal: terminalrc geschrieben" if command -v xfconf-query >/dev/null; then local have=0 command -v xfconf-query >/dev/null && xfconf-query -c xfce4-terminal -l >/dev/null 2>&1 && have=1 if [ "$have" = 1 ]; then xfset() { # xfset if xfconf-query -c xfce4-terminal -p "$1" >/dev/null 2>&1; then run xfconf-query -c xfce4-terminal -p "$1" -t "$2" -s "$3" >/dev/null else run xfconf-query -c xfce4-terminal -p "$1" -n -t "$2" -s "$3" >/dev/null fi } xfset /color-background string "#0b0f14" xfset /color-foreground string "#f5f5ef" xfset /color-cursor string "#c1121f" xfset /color-cursor-use-default bool false xfset /color-use-theme bool false xfset /font-name string "DejaVu Sans Mono 11" xfset /color-palette string "#1a212a;#e0454f;#7fa88c;#c7a46b;#7e93ad;#be8fa0;#8fb3b3;#f5f5ef;#5c6675;#ff6b75;#9cc2a8;#e0c08a;#a3b6cb;#d3a8b8;#aecbcb;#ffffff" ok "xfce4-terminal: laufende Sitzung (xfconf) gesetzt — wichtig, sonst gewinnt das GTK-Theme" else warn "xfconf-query ohne Verbindung zur Sitzung (per SSH normal); terminalrc greift beim naechsten Login" fi fi } xterm_setup() { local xr="$HOME/.Xresources" if [ -f "$xr" ] && grep -qF "Kalina CI" "$xr"; then ok "~/.Xresources: xterm-Block ist schon drin" return 0 fi backup "$xr" if [ "$DRY" = 0 ]; then cat >> "$xr" <<'XRES' ! --- Kalina CI (xterm) ----------------------------------------------------- xterm*background: #0B0F14 xterm*foreground: #F5F5EF xterm*cursorColor: #C1121F xterm*pointerColor: #C1121F xterm*colorBD: #F5F5EF xterm*colorUL: #C1121F xterm*faceName: DejaVu Sans Mono xterm*faceSize: 11 xterm*color0: #1A212A xterm*color1: #E0454F xterm*color2: #7FA88C xterm*color3: #C7A46B xterm*color4: #7E93AD xterm*color5: #BE8FA0 xterm*color6: #8FB3B3 xterm*color7: #F5F5EF xterm*color8: #5C6675 xterm*color9: #FF6B75 xterm*color10: #9CC2A8 xterm*color11: #E0C08A xterm*color12: #A3B6CB xterm*color13: #D3A8B8 xterm*color14: #AECBCB xterm*color15: #FFFFFF ! --- Ende Kalina CI ------------------------------------------------------- XRES fi ok "~/.Xresources: xterm-Farben ergaenzt (aktiv nach 'xrdb -merge ~/.Xresources')" } # ------------------------------------------------------------------- Ablauf say "Kalina CI — Installation auf $(hostname), Ziel $HOME" [ "$DRY" = 1 ] && say "(Probelauf: es wird nichts geschrieben)" [ "$DO_SHELL" = 1 ] && do_shell [ "$DO_TERM" = 1 ] && do_terminal step "Fertig" say " Prompt pruefen: zsh -i (oder neue Terminal-Sitzung)" say " Abschalten: KALINA_CI_PROMPT=0 zsh -i" say " Palette pruefen: Terminal neu starten; nach environment.d-Aenderung einmal neu anmelden"