From 6036648d76e69e44b68f4e54df86b359b4a5d0ce Mon Sep 17 00:00:00 2001 From: h0tznpl0tz Date: Thu, 11 Sep 2025 11:58:15 +0200 Subject: [PATCH] Update install.sh with auto-discovery and README with Quick Start MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Enhanced install.sh with script auto-discovery functionality - Added Quick Start section to README with one-liner commands - Created update.sh for repository updates - Resolved merge conflicts from upstream changes 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- README.md | 41 ++++++- install.sh | 354 +++++++++++++++++++++++++++++++++++++++-------------- update.sh | 247 +++++++++++++++++++++++++++++++++++++ 3 files changed, 552 insertions(+), 90 deletions(-) create mode 100755 update.sh diff --git a/README.md b/README.md index 9b5453f..5265504 100644 --- a/README.md +++ b/README.md @@ -5,12 +5,14 @@ Hier sammeln wir kleine Helfer für Log-Analysen, Automatisierungen und typische ## Inhaltsverzeichnis +- [Quick Start](#quick-start) - [Übersicht](#übersicht) - [Bash-Profile](#bash-profile) - [Connect Tools](#connect-tools) - [Legacy Snippets](#legacy-snippets) - [WH20 Snippets](#wh20-snippets) - [Installation](#installation) +- [Updates](#updates) - [How-To: Neues Skript anlegen](#how-to-neues-skript-anlegen) - [Lizenz / Sichtbarkeit](#lizenz--sichtbarkeit) @@ -52,6 +54,20 @@ Weitere Snippets für Legacy kommen hier dazu. *(noch leer, Platzhalter für künftige Snippets)* +--- + +## Quick Start + +**One-liner Installation:** +```bash +git clone http://vps.dominikus.one:3000/ljp/esn-support-bash-snippets.git esn-support-tools && cd esn-support-tools && ./install.sh +``` + +**One-liner Update:** +```bash +cd esn-support-tools && ./update.sh +``` + ## Installation Nach dem Klonen des Repositories steht ein interaktives Installationsscript zur Verfügung: @@ -59,7 +75,10 @@ Nach dem Klonen des Repositories steht ein interaktives Installationsscript zur ```bash # Repository klonen git clone http://vps.dominikus.one:3000/ljp/esn-support-bash-snippets.git -cd esn-support-bash-snippets + +# WICHTIG: Repository umbenennen (empfohlen) +mv esn-support-bash-snippets esn-support-tools +cd esn-support-tools # Installation testen (empfohlen) ./install.sh --dry-run @@ -71,6 +90,26 @@ cd esn-support-bash-snippets ./install.sh --help ``` +> **⚠️ Wichtiger Hinweis zu Symlinks:** +> Das Installationsscript erstellt Symlinks zu den Scripts im **aktuellen Repository-Pfad**. +> Wenn du das Repository später verschiebst oder umbenennst, funktionieren die installierten Tools nicht mehr. +> **Empfehlung:** Repository vor der Installation in einen permanenten Pfad legen (z.B. `~/tools/esn-support-tools`). + +## Updates + +Für Updates bestehender Installationen: + +```bash +# In Repository-Verzeichnis wechseln +cd /pfad/zu/esn-support-tools + +# Update testen (empfohlen) +./update.sh --dry-run + +# Update durchführen +./update.sh +``` + **Features des Installers:** - **Dry-Run Modus**: `--dry-run` testet Installation ohne Dateiveränderungen - **Interaktive Auswahl**: Kategorien und einzelne Tools wählbar diff --git a/install.sh b/install.sh index aeae8f3..47a4eac 100755 --- a/install.sh +++ b/install.sh @@ -39,6 +39,53 @@ log_dry_run() { echo -e "${YELLOW}[DRY-RUN]${NC} $1" } +# Auto-Discovery Funktionen +discover_scripts() { + local category="$1" + local scripts=() + + if [[ ! -d "$SCRIPT_DIR/$category" ]]; then + echo "0" + return + fi + + # Finde alle .sh Dateien in Unterverzeichnissen + while IFS= read -r -d '' script; do + # Extrahiere Scriptname und Verzeichnis + local script_dir="$(dirname "$script")" + local script_name="$(basename "$script_dir")" + local script_file="$(basename "$script")" + + # Überspringe wenn Script-Name nicht dem Verzeichnis entspricht + if [[ "$script_file" == "$script_name.sh" ]]; then + scripts+=("$script_name:$script") + fi + done < <(find "$SCRIPT_DIR/$category" -name "*.sh" -type f -print0 2>/dev/null) + + # Rückgabe: Anzahl:script1:path1:script2:path2... + local result="${#scripts[@]}" + for script_info in "${scripts[@]}"; do + result="$result:$script_info" + done + echo "$result" +} + +get_script_description() { + local category="$1" + local script_name="$2" + + # Versuche Beschreibung aus README zu extrahieren + local readme="$SCRIPT_DIR/$category/$script_name/README.md" + if [[ -f "$readme" ]]; then + # Erste Zeile nach "# scriptname" + grep -A 2 "^# $script_name" "$readme" 2>/dev/null | tail -n 1 | sed 's/^[[:space:]]*//' + else + # Fallback: Erste Kommentarzeile aus Script + local script_file="$SCRIPT_DIR/$category/$script_name/$script_name.sh" + grep -m 1 "^# " "$script_file" 2>/dev/null | sed 's/^# //' || echo "Keine Beschreibung verfügbar" + fi +} + # Hilfsfunktionen backup_file() { local file="$1" @@ -126,117 +173,246 @@ install_bashprofiles() { esac } +# Generische Script-Installation +install_script() { + local category="$1" + local script_name="$2" + local script_path="$3" + + log_info "Installiere $script_name..." + + # Spezielle Behandlung für go-Tool (LUSER check) + if [[ "$script_name" == "go" ]]; then + if [[ -z "${LUSER:-}" ]]; then + log_warning "LUSER Umgebungsvariable nicht gesetzt" + if [[ "$DRY_RUN" == "true" ]]; then + log_dry_run "Würde nach LUSER fragen und in ~/.bash_env schreiben" + log_dry_run "Beispiel: export LUSER=\"username\" >> ~/.bash_env" + else + read -p "LUSER eingeben (für Kerberos): " user_input + if [[ -n "$user_input" ]]; then + echo "export LUSER=\"$user_input\"" >> "$HOME/.bash_env" + export LUSER="$user_input" + log_success "LUSER in ~/.bash_env gesetzt" + fi + fi + else + log_info "LUSER bereits gesetzt: $LUSER" + fi + fi + + # Script ausführbar machen + make_executable "$script_path" + + # Symlink erstellen + ensure_bin_dir + create_symlink "$script_path" "$HOME/bin/$script_name" "$script_name-Tool" + + log_success "$script_name installiert" +} + +ensure_bin_dir() { + if [[ ! -d "$HOME/bin" ]]; then + if [[ "$DRY_RUN" == "true" ]]; then + log_dry_run "Würde Verzeichnis erstellen: ~/bin" + log_dry_run "Würde PATH erweitern: export PATH=\"\$HOME/bin:\$PATH\" >> ~/.bash_paths" + else + log_info "~/bin existiert nicht. Erstelle Verzeichnis..." + mkdir -p "$HOME/bin" + log_info "Füge ~/bin zu PATH hinzu (in ~/.bash_paths)" + echo 'export PATH="$HOME/bin:$PATH"' >> "$HOME/.bash_paths" + fi + fi +} + # Installation: Connect Tools install_connect() { log_info "=== Connect Tools Installation ===" + # Auto-discover verfügbare Scripts + local discovery_result + discovery_result=$(discover_scripts "connect") + + local script_count + script_count=$(echo "$discovery_result" | cut -d':' -f1) + + if [[ "$script_count" -eq 0 ]]; then + log_info "Keine Connect Tools gefunden" + return + fi + echo -e "\n${PURPLE}Verfügbare Tools:${NC}" - echo "1) go - SSH-Shortcuts für easyname Server" + + # Parse discovery result und zeige Menu + local scripts=() + local counter=1 + IFS=':' read -ra PARTS <<< "$discovery_result" + for ((i=1; i<${#PARTS[@]}; i+=2)); do + local script_name="${PARTS[i]}" + local script_path="${PARTS[i+1]}" + local description + description=$(get_script_description "connect" "$script_name") + + echo "$counter) $script_name - $description" + scripts+=("$script_name:$script_path") + ((counter++)) + done + + echo "$counter) Alle Connect Tools" echo "0) Überspringen" - read -p "Tools auswählen [0-1]: " connect_choice + read -p "Tools auswählen [0-$counter]: " connect_choice - case "$connect_choice" in - 1) - log_info "Installiere go SSH-Shortcut Tool..." - - # Prüfe LUSER Variable - if [[ -z "${LUSER:-}" ]]; then - log_warning "LUSER Umgebungsvariable nicht gesetzt" - if [[ "$DRY_RUN" == "true" ]]; then - log_dry_run "Würde nach LUSER fragen und in ~/.bash_env schreiben" - log_dry_run "Beispiel: export LUSER=\"username\" >> ~/.bash_env" - else - read -p "LUSER eingeben (für Kerberos): " user_input - if [[ -n "$user_input" ]]; then - echo "export LUSER=\"$user_input\"" >> "$HOME/.bash_env" - export LUSER="$user_input" - log_success "LUSER in ~/.bash_env gesetzt" - fi - fi - else - log_info "LUSER bereits gesetzt: $LUSER" - fi - - # Script installieren - local go_script="$SCRIPT_DIR/connect/go/go.sh" - make_executable "$go_script" - - # Symlink in ~/bin oder PATH erstellen - if [[ -d "$HOME/bin" ]]; then - create_symlink "$go_script" "$HOME/bin/go" "go-Tool" - else - if [[ "$DRY_RUN" == "true" ]]; then - log_dry_run "Würde Verzeichnis erstellen: ~/bin" - log_dry_run "Würde PATH erweitern: export PATH=\"\$HOME/bin:\$PATH\" >> ~/.bash_paths" - else - log_info "~/bin existiert nicht. Erstelle Verzeichnis..." - mkdir -p "$HOME/bin" - log_info "Füge ~/bin zu PATH hinzu (in ~/.bash_paths)" - echo 'export PATH="$HOME/bin:$PATH"' >> "$HOME/.bash_paths" - fi - create_symlink "$go_script" "$HOME/bin/go" "go-Tool" - fi - - log_success "go-Tool installiert" - ;; - 0) - log_info "Connect Tools übersprungen" - ;; - *) - log_error "Ungültige Auswahl" - ;; - esac + if [[ "$connect_choice" -eq 0 ]]; then + log_info "Connect Tools übersprungen" + elif [[ "$connect_choice" -eq "$counter" ]]; then + # Alle installieren + for script_info in "${scripts[@]}"; do + IFS=':' read -r script_name script_path <<< "$script_info" + install_script "connect" "$script_name" "$script_path" + done + elif [[ "$connect_choice" -ge 1 && "$connect_choice" -lt "$counter" ]]; then + # Einzelnes Tool installieren + local selected_script="${scripts[$((connect_choice-1))]}" + IFS=':' read -r script_name script_path <<< "$selected_script" + install_script "connect" "$script_name" "$script_path" + else + log_error "Ungültige Auswahl" + fi } # Installation: Legacy Tools install_legacy() { log_info "=== Legacy Tools Installation ===" + # Auto-discover verfügbare Scripts + local discovery_result + discovery_result=$(discover_scripts "legacy") + + local script_count + script_count=$(echo "$discovery_result" | cut -d':' -f1) + + if [[ "$script_count" -eq 0 ]]; then + log_info "Keine Legacy Tools gefunden" + return + fi + echo -e "\n${PURPLE}Verfügbare Tools:${NC}" - echo "1) checkms - MS-Fehlercode Analyse" - echo "2) quicknav - Bash-Funktion für schnelle Navigation" - echo "3) Alle Legacy Tools" + + # Parse discovery result und zeige Menu + local scripts=() + local counter=1 + IFS=':' read -ra PARTS <<< "$discovery_result" + for ((i=1; i<${#PARTS[@]}; i+=2)); do + local script_name="${PARTS[i]}" + local script_path="${PARTS[i+1]}" + local description + description=$(get_script_description "legacy" "$script_name") + + echo "$counter) $script_name - $description" + scripts+=("$script_name:$script_path") + ((counter++)) + done + + echo "$counter) Alle Legacy Tools" echo "0) Überspringen" - read -p "Tools auswählen [0-3]: " legacy_choice + read -p "Tools auswählen [0-$counter]: " legacy_choice - case "$legacy_choice" in - 1|3) - log_info "Installiere checkms..." - local checkms_script="$SCRIPT_DIR/legacy/checkms/checkms.sh" - make_executable "$checkms_script" - - if [[ -d "$HOME/bin" ]]; then - create_symlink "$checkms_script" "$HOME/bin/checkms" "checkms" - else - mkdir -p "$HOME/bin" - create_symlink "$checkms_script" "$HOME/bin/checkms" "checkms" - fi - - log_success "checkms installiert" - ;;& - 2|3) - log_info "Installiere quicknav..." - local quicknav_func="$SCRIPT_DIR/legacy/quicknav/quicknav.sh" - - log_warning "quicknav ist eine Bash-Funktion und muss manuell in .bashrc eingebunden werden" - log_info "Füge folgende Zeile zu ~/.bashrc hinzu:" - echo -e "${YELLOW}source \"$quicknav_func\"${NC}" - ;;& - 0) - log_info "Legacy Tools übersprungen" - ;; - *) - log_error "Ungültige Auswahl" - ;; - esac + if [[ "$legacy_choice" -eq 0 ]]; then + log_info "Legacy Tools übersprungen" + elif [[ "$legacy_choice" -eq "$counter" ]]; then + # Alle installieren + for script_info in "${scripts[@]}"; do + IFS=':' read -r script_name script_path <<< "$script_info" + install_legacy_script "$script_name" "$script_path" + done + elif [[ "$legacy_choice" -ge 1 && "$legacy_choice" -lt "$counter" ]]; then + # Einzelnes Tool installieren + local selected_script="${scripts[$((legacy_choice-1))]}" + IFS=':' read -r script_name script_path <<< "$selected_script" + install_legacy_script "$script_name" "$script_path" + else + log_error "Ungültige Auswahl" + fi } -# Installation: WH20 Tools (Platzhalter für zukünftige Tools) +# Spezielle Legacy Script Installation (für quicknav Behandlung) +install_legacy_script() { + local script_name="$1" + local script_path="$2" + + log_info "Installiere $script_name..." + + if [[ "$script_name" == "quicknav" ]]; then + # quicknav ist eine Bash-Funktion, keine Binary + log_warning "quicknav ist eine Bash-Funktion und muss manuell in .bashrc eingebunden werden" + if [[ "$DRY_RUN" == "true" ]]; then + log_dry_run "Würde Hinweis anzeigen: source \"$script_path\" zu ~/.bashrc hinzufügen" + else + log_info "Füge folgende Zeile zu ~/.bashrc hinzu:" + echo -e "${YELLOW}source \"$script_path\"${NC}" + fi + else + # Normale Script Installation + install_script "legacy" "$script_name" "$script_path" + fi +} + +# Installation: WH20 Tools install_wh20() { log_info "=== WH20 Tools Installation ===" - log_info "Noch keine WH20 Tools verfügbar" + + # Auto-discover verfügbare Scripts + local discovery_result + discovery_result=$(discover_scripts "wh20") + + local script_count + script_count=$(echo "$discovery_result" | cut -d':' -f1) + + if [[ "$script_count" -eq 0 ]]; then + log_info "Noch keine WH20 Tools verfügbar" + return + fi + + echo -e "\n${PURPLE}Verfügbare Tools:${NC}" + + # Parse discovery result und zeige Menu + local scripts=() + local counter=1 + IFS=':' read -ra PARTS <<< "$discovery_result" + for ((i=1; i<${#PARTS[@]}; i+=2)); do + local script_name="${PARTS[i]}" + local script_path="${PARTS[i+1]}" + local description + description=$(get_script_description "wh20" "$script_name") + + echo "$counter) $script_name - $description" + scripts+=("$script_name:$script_path") + ((counter++)) + done + + echo "$counter) Alle WH20 Tools" + echo "0) Überspringen" + + read -p "Tools auswählen [0-$counter]: " wh20_choice + + if [[ "$wh20_choice" -eq 0 ]]; then + log_info "WH20 Tools übersprungen" + elif [[ "$wh20_choice" -eq "$counter" ]]; then + # Alle installieren + for script_info in "${scripts[@]}"; do + IFS=':' read -r script_name script_path <<< "$script_info" + install_script "wh20" "$script_name" "$script_path" + done + elif [[ "$wh20_choice" -ge 1 && "$wh20_choice" -lt "$counter" ]]; then + # Einzelnes Tool installieren + local selected_script="${scripts[$((wh20_choice-1))]}" + IFS=':' read -r script_name script_path <<< "$selected_script" + install_script "wh20" "$script_name" "$script_path" + else + log_error "Ungültige Auswahl" + fi } # Hilfsfunktion diff --git a/update.sh b/update.sh new file mode 100755 index 0000000..73c4f0e --- /dev/null +++ b/update.sh @@ -0,0 +1,247 @@ +#!/usr/bin/env bash +# update.sh - Update-Script für easyname Support Bash-Snippets +# Aktualisiert Repository und re-linkt installierte Tools + +set -euo pipefail + +# Farben für Output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +PURPLE='\033[0;35m' +NC='\033[0m' # No Color + +# Script-Verzeichnis ermitteln +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +# Dry-run Modus +DRY_RUN=false + +# Logging-Funktionen +log_info() { + echo -e "${BLUE}[INFO]${NC} $1" +} + +log_success() { + echo -e "${GREEN}[SUCCESS]${NC} $1" +} + +log_warning() { + echo -e "${YELLOW}[WARNING]${NC} $1" +} + +log_error() { + echo -e "${RED}[ERROR]${NC} $1" +} + +log_dry_run() { + echo -e "${YELLOW}[DRY-RUN]${NC} $1" +} + +# Hilfsfunktionen +check_git_repo() { + if [[ ! -d "$SCRIPT_DIR/.git" ]]; then + log_error "Kein Git-Repository gefunden in $SCRIPT_DIR" + log_error "Bitte das Repository ordnungsgemäß klonen!" + exit 1 + fi +} + +backup_current_state() { + local backup_dir="$SCRIPT_DIR/.update_backup_$(date +%Y%m%d_%H%M%S)" + + if [[ "$DRY_RUN" == "true" ]]; then + log_dry_run "Würde Backup erstellen: $backup_dir" + return + fi + + log_info "Erstelle Backup des aktuellen Zustands..." + mkdir -p "$backup_dir" + + # Backup wichtiger Dateien falls sie modifiziert wurden + for file in "install.sh" "update.sh" "README.md"; do + if [[ -f "$SCRIPT_DIR/$file" ]]; then + cp "$SCRIPT_DIR/$file" "$backup_dir/" + fi + done + + log_success "Backup erstellt: $backup_dir" +} + +update_repository() { + log_info "Aktualisiere Repository..." + + if [[ "$DRY_RUN" == "true" ]]; then + log_dry_run "Würde ausführen: git fetch origin" + log_dry_run "Würde ausführen: git pull origin main" + return + fi + + # Fetch latest changes + if ! git fetch origin; then + log_error "Fehler beim Fetch der Remote-Änderungen" + exit 1 + fi + + # Check if updates available + local local_commit + local_commit=$(git rev-parse HEAD) + local remote_commit + remote_commit=$(git rev-parse origin/main) + + if [[ "$local_commit" == "$remote_commit" ]]; then + log_info "Repository ist bereits auf dem neuesten Stand" + return 0 + fi + + log_info "Updates gefunden, führe Pull durch..." + if ! git pull origin main; then + log_error "Fehler beim Pull der Änderungen" + log_error "Bitte manuell lösen und erneut versuchen" + exit 1 + fi + + log_success "Repository erfolgreich aktualisiert" + return 1 # Updates wurden angewendet +} + +find_installed_tools() { + local installed_tools=() + + # Suche nach Symlinks in ~/bin die auf dieses Repository zeigen + if [[ -d "$HOME/bin" ]]; then + while IFS= read -r -d '' symlink; do + local target + target=$(readlink "$symlink") + + # Prüfe ob Symlink auf dieses Repository zeigt + if [[ "$target" == "$SCRIPT_DIR"* ]]; then + local tool_name + tool_name=$(basename "$symlink") + installed_tools+=("$tool_name:$target") + fi + done < <(find "$HOME/bin" -type l -print0 2>/dev/null || true) + fi + + printf '%s\n' "${installed_tools[@]}" +} + +relink_tools() { + log_info "Suche installierte Tools..." + + local installed_tools + mapfile -t installed_tools < <(find_installed_tools) + + if [[ ${#installed_tools[@]} -eq 0 ]]; then + log_info "Keine installierten Tools gefunden" + return + fi + + log_info "Gefundene Tools: ${#installed_tools[@]}" + + for tool_info in "${installed_tools[@]}"; do + IFS=':' read -r tool_name old_target <<< "$tool_info" + local symlink_path="$HOME/bin/$tool_name" + + log_info "Aktualisiere Symlink für: $tool_name" + + if [[ "$DRY_RUN" == "true" ]]; then + log_dry_run "Würde Symlink aktualisieren: $symlink_path -> $old_target" + else + # Symlink neu erstellen (aktualisiert automatisch den Pfad) + ln -sf "$old_target" "$symlink_path" + log_success "$tool_name Symlink aktualisiert" + fi + done +} + +# Hilfsfunktion +show_help() { + cat <