niceos:script_launcher_bh
Это старая версия документа!
Содержание
Script Launcher
Linux
Проверено на Raspberry Pi4/5 OS

Скрипт перебирает все скрипты *.sh в каталоге запуска и подкаталогах, если имеет доступ
и отбирают те в которых есть # ==AUTOEXEC==
#!/bin/bash # ==AUTOEXEC== # === Название программы === # Строка для основного описания # Строки для развернутого описания # Строки для развернутого описания #
строка для основного описания будет отображена следом за названием скрипта *.sh через *
признаком окончания описания является первая первая найденная строка где кроме # ничего нет
Шаблон скрипта
Шаблон оформления скрипта для применения в лаунчере
Дополнительно сделан шаблон меню с выбором пунктов
Шаблон файла с заголовками для использования в лаунчере (нажмите чтобы раскрыть)
- template.sh
#!/bin/bash # ==AUTOEXEC== # === Шаблон меню для нового скрипта === # * Основной шаблон bash-скрипта с пунктами меню и выходом по 0 # * Добавьте сюда свои действия и команды # PS3="📌 Выберите действие: " echo " 0) ❌ Выход" select action in "📂 Действие 1" "⚙️ Действие 2" "❌ Выход"; do if [[ "$REPLY" == "0" ]]; then echo "👋 До свидания!" exit 0 fi case $REPLY in 1) echo "👉 Выполняем Действие 1" # ваша команда здесь ;; 2) echo "🔧 Выполняем Действие 2" # ваша команда здесь ;; 3) echo "👋 До свидания!" exit 0 ;; *) echo "❗ Неверный выбор";; esac break done exit 0
Лаунчер
- launcher.sh
#!/bin/bash export LANG=en_US.UTF-8 export LC_ALL=en_US.UTF-8 # === 🚀Лаунчер === # ищет в основном каталоге и подкаталогах * # файлы *.sh с ==AUTOEXEC== в шапке и создает список из таких файлов * # с возможностью запуска * # поддерживает режимы: включённые каталоги / исключённые каталоги * # можно задавать глубину вложенности и абсолютные/относительные пути * INCLUDE_MARKER="# ==AUTOEXEC==" ROOT_DIR="$(pwd)" TMP_LIST="/tmp/script_launcher_list.txt" SELECTED_FILE="" # Каталоги, которые нужно исключить (используются в режиме exclude) EXCLUDE_DIRS=("scripts_arch" "backup_temp" "rpi_seal_arch") # Каталоги, которые нужно включить (используются в режиме include) INCLUDE_DIRS=("scripts" "rpi_seal") # Глубина вложенности (0 = без ограничений) MIN_DEPTH=0 MAX_DEPTH=0 # Режим поиска: include — искать только в указанных каталогах, # exclude — искать везде, кроме исключённых SEARCH_MODE="include" # --- Проверка fzf --- HAS_FZF=false if command -v fzf &>/dev/null; then HAS_FZF=true fi # --- Сбор скриптов (.sh) --- > "$TMP_LIST" SEPARATOR=" _ _ " FIND_CONDITION="" [[ "$MIN_DEPTH" -gt 0 ]] && FIND_CONDITION+=" -mindepth $MIN_DEPTH" [[ "$MAX_DEPTH" -gt 0 ]] && FIND_CONDITION+=" -maxdepth $MAX_DEPTH" if [[ "$SEARCH_MODE" == "include" ]]; then for DIR in "${INCLUDE_DIRS[@]}"; do [ -d "$DIR" ] || continue find "$DIR" $FIND_CONDITION -type f -name "*.sh" 2>/dev/null done else EXCLUDE_EXPR="" for DIR in "${EXCLUDE_DIRS[@]}"; do ABS_DIR=$(realpath "$DIR") EXCLUDE_EXPR+=" -path \"$ABS_DIR\" -o" done EXCLUDE_EXPR="${EXCLUDE_EXPR::-3}" eval "find \"$ROOT_DIR\" \( $EXCLUDE_EXPR \) -prune -o $FIND_CONDITION -type f -name \"*.sh\" -print" 2>/dev/null fi | sort | while read -r FILE; do if grep -q "^$INCLUDE_MARKER" "$FILE"; then TITLE="" SHORT="" found_title=false while IFS= read -r line; do [[ -z "$line" ]] && break if [[ "$line" =~ ^# ]]; then CLEANED="${line#\# }" if [[ "$CLEANED" =~ ^===.*=== ]]; then TITLE="$(echo "$CLEANED" | sed -E 's/^=== *(.*?) *===$/\1/')" found_title=true elif [[ "$found_title" = true && -z "$SHORT" ]]; then SHORT="$CLEANED" fi fi done < <(tail -n +2 <(grep -A30 "^$INCLUDE_MARKER" "$FILE")) TITLE=${TITLE:-"(Без названия)"} DISPLAY_LINE="$TITLE" [ -n "$SHORT" ] && DISPLAY_LINE+=" * $SHORT" echo "$DISPLAY_LINE$SEPARATOR$FILE" >> "$TMP_LIST" fi done if [ ! -s "$TMP_LIST" ]; then echo "❌ Не найдено подходящих скриптов." exit 1 fi # --- Предпросмотр --- PREVIEW_CMD=$(cat <<'EOF' FILE=$(echo {} | awk -F " _ _ " '{print $2}') if [ -f "$FILE" ]; then ENCODING=$(file -bi "$FILE" | cut -d= -f2) if [ "$ENCODING" != "utf-8" ]; then echo "⚠️ Кодировка файла: $ENCODING (not UTF-8)" echo "Могут быть проблемы с отображением." echo "" fi BASENAME=$(basename "$FILE") TITLE_LINE=$(awk '/^# ==AUTOEXEC==/{flag=1; next} /^$/{flag=0} flag && /^#/ && /===.*===/ { sub(/^# ?=== */, "", $0); sub(/ *===$/, "", $0); print; exit }' "$FILE") echo -e "📄 $BASENAME\n📂 $FILE\n\n📛 $TITLE_LINE\n" awk '/^# ==AUTOEXEC==/{flag=1; next} /^$/{flag=0} flag && /^#/ && !/===.*===/ { sub(/^# ?(\* )?/, "", $0); print }' "$FILE" else echo "❌ Файл не найден: $FILE" fi EOF ) # --- Выбор интерфейса запуска --- while true; do echo "📦 Выберите режим запуска:" echo " 1 - 🚀fzf-интерфейс $([ "$HAS_FZF" = true ] && echo "(доступен)" || echo "(недоступен)")" echo " 2 - 📄Классическое текстовое меню" echo " 0 - ❌Выход" echo -n ">> " read -r launcher_mode case "$launcher_mode" in 1) if [ "$HAS_FZF" = true ]; then SELECTED_LINE=$(fzf --prompt="🚀 Выберите скрипт: " \ --delimiter="$SEPARATOR" \ --preview="$PREVIEW_CMD" \ --preview-window=right:60%:wrap \ < "$TMP_LIST") if [ -z "$SELECTED_LINE" ]; then echo "❎ Отмена пользователем." rm -f "$TMP_LIST" exit 0 fi SELECTED_FILE=$(echo "$SELECTED_LINE" | awk -F "$SEPARATOR" '{print $2}' | xargs) break else echo "⚠️ fzf не установлен. Установите с помощью:" echo " sudo apt update && sudo apt install -y fzf" launcher_mode=2 fi ;; 2) echo "📜 Найденные скрипты:" echo " 0) ❌ Выход" echo mapfile -t ENTRIES < <(awk -F "$SEPARATOR" '{print $1}' "$TMP_LIST") ENTRIES+=("❌ Выход") PS3="📌 Выберите скрипт: " select ENTRY in "${ENTRIES[@]}"; do if [[ "$REPLY" == "0" || "$ENTRY" == "❌ Выход" ]]; then echo "👋 До свидания!"; rm -f "$TMP_LIST"; exit 0 fi [ -z "$ENTRY" ] && echo "❌ Неверный выбор" && continue SELECTED_FILE=$(grep -F "$ENTRY" "$TMP_LIST" | head -n1 | awk -F "$SEPARATOR" '{print $2}' | xargs) break 2 done ;; 0) echo "👋 До свидания!" rm -f "$TMP_LIST" exit 0 ;; *) echo "❌ Неверный выбор" ;; esac done # --- Подтверждение и запуск --- echo "⚠️ Скрипт: $SELECTED_FILE" echo "Запустить его? (y/N):" read -r confirm if [[ "$confirm" =~ ^[Yy]$ ]]; then echo "🚀 Запуск..." EXT="${SELECTED_FILE##*.}" case "$EXT" in sh) bash "$SELECTED_FILE" ;; py) python3 "$SELECTED_FILE" ;; *) echo "❌ Неизвестный тип файла: $EXT" ;; esac else echo "❎ Отмена." fi rm -f "$TMP_LIST"
Описание
- script_launcher.md
# 🚀 Лаунчер скриптов (версия V4) **Дата создания:** 2025-04-05 ## 📄 Описание Этот Bash-скрипт выполняет поиск и запуск `.sh`-файлов, содержащих маркер `# ==AUTOEXEC==` в шапке. Он поддерживает два режима поиска: - `exclude` — поиск от корня, исключая определённые каталоги. - `include` — поиск только в явно указанных каталогах. ## ⚙️ Переменные настройки | Переменная | Назначение | |----------------|--------------------------------------------------------------------------------| | `MODE` | Режим поиска: `auto` / `manual` (в этом варианте используется `exclude`) | | `ROOT_DIR` | Корневая директория поиска в режиме `exclude` | | `INCLUDE_DIRS` | Каталоги для поиска в режиме `include` (можно задать относительные/абсолютные) | | `EXCLUDE_DIRS` | Каталоги, исключаемые из поиска | | `MIN_DEPTH` | Минимальная глубина вложенности (0 — без ограничений) | | `MAX_DEPTH` | Максимальная глубина вложенности (0 — без ограничений) | | `SEPARATOR` | Разделитель между заголовком и путём в списке | | `TMP_LIST` | Временный файл для хранения списка найденных скриптов | ## 🧩 Логика 1. Выполняется поиск `.sh`-файлов с учётом глубины и включений/исключений. 2. Извлекаются заголовок (`# === Название ===`) и краткое описание. 3. Создаётся список скриптов, отображаемый через: - `fzf` (при наличии), - или классическое Bash-меню. 4. Запуск выбранного скрипта с подтверждением. ## 🔍 Пример использования Просто запустить: ```bash ./launcher.sh ``` ## 🗂 Пример структуры проекта ``` project/ ├── launcher.sh ├── scripts/ │ ├── backup.sh │ ├── update.sh ├── scripts_arch/ │ └── old_backup.sh ``` ## 🛡️ Советы - Убедитесь, что скрипты имеют маркер `# ==AUTOEXEC==` и заголовок `# === Название ===`. - Скрипт работает стабильно с абсолютными и относительными путями. - Для предпросмотра `fzf` необходим пакет `fzf`.
Приписка
niceos/script_launcher_bh.1743848696.txt.gz · Последнее изменение: —
