Linux · автоматизация

Моята система за управление и търсене на Linux команди

Как превърнах терминала си в интерактивна база данни: търсене с fzf, преглед на живо, бърз клипборд и интелигентна история с Ctrl+H.

Когато работя в терминала — независимо дали е във WSL2 на Windows, локален Ubuntu сървър или Proxmox LXC контейнер — ежедневно си имам работа с десетки специфични команди. Дълги rsync синтаксиси, docker филтри, Cloudflare CLI параметри или специфични grep опции.

Преди време разчитах на обикновения history или на бележки в текстови файлове. Но ровенето и постоянното копиране/поставяне губи време. Затова си изградих собствена лека система за управление на команди, базирана на fzf (Fuzzy Finder), обикновен текстов файл и няколко удобни Bash функции. Използвам я от доста време и работи безупречно.

1. Защо създадох тази система?

Основният проблем с трупането на команди в стандартната история на Bash е, че тя съдържа много „шум“ — грешно изписани команди, временни директории, повтарящи се ls и cd.

Моята цел беше да имам:

  • Лична база с изпитани команди: Файл, в който записвам само важните и сложни команди с кратко описание и тагове.
  • Бърз fuzzy search: Натискам една команда, пиша 2-3 букви и виждам точния резултат.
  • Автоматично копиране в клипборда: Командата да се копира директно в системния клипборд (работи безупречно както в чист Linux, така и в WSL през clip.exe).
  • Интерактивен преглед (Preview window): Стилна кутия, която показва описанието, таговете и самата команда с оцветяване преди да я избера.

2. Базата данни: Файлът ~/.commands.txt

Всички команди се съхраняват в обикновен текстов файл в домашната директория: ~/.commands.txt. Това е сърцето на системата — лесен за редакция, лесен за споделяне с колеги и лесен за възстановяване след преинсталация.

Форматът е изключително прост. Всеки ред съдържа точно 3 елемента, разделени от ||:

Структура на реда
Описание || тагове || команда
  • Описание — кратко, на човешки език (какво прави командата).
  • Тагове — ключови думи за търсене (docker, rsync, network…), разделени със запетая.
  • Команда — самият ред, който се копира в клипборда.

Редовете, започващи с #, се третират като коментари и се игнорират от fzf. Празните редове също се пропускат.

Първоначална настройка: touch ~/.commands.txt  ·  После отвори с nano ~/.commands.txt или ползвай cmdedit (виж по-долу).

Ето пълен готов пример — можеш да го копираш директно в ~/.commands.txt и веднага да започнеш. Включва архивиране, Docker, Git, търсене, мрежа, rsync, права и още. Променяй пътища, IP адреси и имена според твоята среда.

Пълен ~/.commands.txt (готов за копиране)
# =============================================================================
#  ~/.commands.txt — лична база от Linux команди
#  Формат:  Описание || тагове || команда
#  Автор:   Федя Серафиев · https://fedia.eu/linux/sistema-za-upravlenie-na-komandi-fzf
#
#  Употреба:
#    cmd          → търсене с fzf + копиране в клипборда
#    cmdadd ...   → добавяне на нов ред
#    cmdedit      → редакция с nano
#    cmdlist      → табличен преглед
# =============================================================================


# ==========================================
# АРХИВИРАНЕ И КОМПРЕСИЯ
# ==========================================
Създай tar.gz архив || tar,архив,компресия,backup || tar -czf backup.tar.gz folder/
Разархивирай tar.gz || tar,разархивиране,extract || tar -xzf archive.tar.gz
Виж съдържанието на архив || tar,list,view || tar -tzf archive.tar.gz
Създай zip архив || zip,архив,компресия || zip -r archive.zip folder/
Разархивирай zip || zip,unzip,extract || unzip archive.zip
Създай архив с изключения || tar,exclude,backup || tar -czf backup.tar.gz --exclude='*.log' folder/


# ==========================================
# DOCKER
# ==========================================
Изчисти всичко в Docker || docker,clean,prune,cleanup || docker system prune -a --volumes
Влез в контейнер || docker,exec,bash,shell || docker exec -it container_name bash
Виж логове в реално време || docker,logs,tail || docker logs -f --tail 100 container_name
Спри всички контейнери || docker,stop,kill || docker stop $(docker ps -q)
Изтрий неизползвани образи || docker,images,clean || docker image prune -a
Виж ресурсите на контейнерите || docker,stats,resources || docker stats --no-stream
Покажи всички локални образи || docker,images,list || docker images
Покажи всички контейнери (и спрели) || docker,ps,all || docker ps -a
Създай нова Docker мрежа || docker,network,create || docker network create network_name
Стартирай docker-compose в фон || docker,compose,up || docker-compose up -d


# ==========================================
# GIT
# ==========================================
Красив git log || git,log,history,graph || git log --oneline --graph --all --decorate
Отмени последния commit (запази промените) || git,reset,undo || git reset --soft HEAD~1
Виж разликите преди commit || git,diff,changes || git diff --staged
Търси в историята || git,search,grep || git log --all --grep='search term'
Изтрий локален branch || git,branch,delete || git branch -d branch_name
Клонирай само последния commit || git,clone,shallow || git clone --depth 1 repo_url


# ==========================================
# ТЪРСЕНЕ И ФАЙЛОВЕ
# ==========================================
Намери файлове по име || find,search,locate || find . -name "*.log"
Намери големи файлове || find,size,disk || find . -type f -size +100M
Изтрий стари логове || find,delete,cleanup,old || find . -name "*.log" -mtime +30 -delete
Търси текст във файлове || grep,search,text || grep -rn --exclude-dir=node_modules "текст" .
Търси и покажи само имената || grep,files,list || grep -rl "текст" /path/
Преименувай разширения масово || rename,extension,batch || for f in *.txt; do mv "$f" "${f%.txt}.md"; done
Намери пътя към изпълним файл || which,path,binary || which команда


# ==========================================
# СИСТЕМНИ КОМАНДИ
# ==========================================
Виж заети портове || ports,ss,listening || sudo ss -tulpn
Процеси по CPU || top,processes,cpu || ps aux --sort=-%cpu | head -n 10
Процеси по памет || top,processes,memory,ram || ps aux --sort=-%mem | head -n 10
Дисково пространство || disk,space,df,storage || df -h
Размер на папки в текущата директория || disk,du,folder,size || du -sh * | sort -h
Системна информация накратко || info,system,hardware || lscpu && free -h && df -h
Свободна памет || memory,ram,free || free -h


# ==========================================
# МРЕЖА
# ==========================================
Тествай връзка с ping || network,ping,test || ping -c 4 google.com
Виж активни слушащи портове || network,connections,ss || ss -tuln
Проверка на DNS || dns,nslookup,resolve || nslookup domain.com
Тиха HTTP заявка || curl,http,silent || curl -s https://example.com/ | head -n 20
HTTP хедъри и статус || curl,headers,status || curl -I https://example.com/
Изтегли файл с продължаване || download,wget,curl || wget -c url_to_file
SHA-256 контролна сума || hash,sha256,checksum || sha256sum file.tar


# ==========================================
# RSYNC И BACKUP
# ==========================================
Синхронизирай папки с прогрес || rsync,sync,backup,copy || rsync -avzP source/ dest/
Синхронизирай през SSH || rsync,ssh,remote,backup || rsync -avzP -e ssh source/ user@host:/dest/
Синхронизирай с изтриване (mirror) || rsync,sync,mirror,delete || rsync -avzP --delete source/ dest/
Dry run преди синхронизация || rsync,test,preview || rsync -avzP --dry-run source/ dest/


# ==========================================
# SCP (бърз трансфер)
# ==========================================
SCP: сървър → локално (рекурсивно) || scp,download,remote || scp -r user@host:/path/ /local/
SCP: локално → сървър || scp,upload,remote || scp file user@host:/path/
SCP с нестандартен порт || scp,port || scp -P 2222 -r ./site user@host:/path/


# ==========================================
# PERMISSIONS И OWNERSHIP
# ==========================================
Смени собственик рекурсивно || chown,owner,recursive || sudo chown -R user:group /path/
Права 755 за папки || chmod,permissions,folders || find . -type d -exec chmod 755 {} \;
Права 644 за файлове || chmod,permissions,files || find . -type f -exec chmod 644 {} \;
Направи скрипт изпълним || chmod,executable,script || chmod +x script.sh
Права за частен SSH ключ || ssh,key,chmod,private || chmod 600 id_rsa
Права за публичен SSH ключ || ssh,key,chmod,public || chmod 644 id_rsa.pub


# ==========================================
# TEXT PROCESSING
# ==========================================
Замени текст във файл || sed,replace,substitute || sed -i 's/old/new/g' file.txt
Покажи само уникални редове || sort,unique,distinct || sort file.txt | uniq
Брой редове във файл || wc,count,lines || wc -l file.txt
Извади колона от CSV || cut,csv,column || cut -d',' -f1 file.csv
Обедини файлове || cat,merge,combine || cat file1.txt file2.txt > merged.txt


# ==========================================
# СИСТЕМА И ПАКЕТИ
# ==========================================
Update + upgrade || apt,update,upgrade || sudo apt update && sudo apt upgrade -y
Cleanup след upgrade || apt,autoremove,clean || sudo apt autoremove -y && sudo apt autoclean
Локален HTTP сървър || python,http,server,local || python3 -m http.server 8080


# ==========================================
# PROXMOX / LXC
# ==========================================
Списък с контейнери в Proxmox || proxmox,pct,list || pct list


# ==========================================
# РАЗНИ ПОЛЕЗНИ
# ==========================================
Хеширане на низ с SHA-256 || hash,openssl,sha256 || echo -n "mypassword" | openssl dgst -sha256
Преименувай / премести || mv,rename,move || mv старо_име ново_име
Копирай директория рекурсивно || cp,copy,recursive || cp -r source_dir copy_dir
Провери дали процес/скрипт работи || ps,grep,process || ps -ef | grep script_name
Deploy статичен сайт (Cloudflare Pages) || wrangler,pages,deploy || npx wrangler pages deploy . --project-name=PROJECT_NAME


# =============================================================================
#  КРАЙ — добавяй нови редове в същия формат
# =============================================================================
За колеги и след преинсталация: копирай целия блок по-горе → nano ~/.commands.txt → постави → запази. Или дръж резервно копие на USB / в облак / в git. Един файл = цялата ти база.

3. Как работи архитектурата?

Системата разчита на съвместната работа между текстовия файл и няколко скрипта в ~/.bashrc:

  1. Парсиране с grep и fzf: Чете файла, филтрира коментарите (редовете, започващи с #) и го подава на fzf.
  2. Сплитване и визуализация: Чрез CLI инструментите cut и sed, fzf разделя трите секции и ги оцветява в интерактивния прозорец за преглед.
  3. Автоматично засичане на средата: Засича дали сте във WSL (Windows Subsystem for Linux) или стандартен Linux, за да изпрати избраната команда към правилния клипборд.

4. Пълният конфигурационен код (~/.bashrc)

Ето целия фрагмент, който трябва да добавите в края на вашия ~/.bashrc файл:

Конфигурация за ~/.bashrc
# ==========================================
# Система за управление на Linux команди
# ==========================================
# Търсене и копиране на команда
cmd() {
    local selected=$(cat ~/.commands.txt | grep -v "^#" | grep -v "^$" | \
        fzf --height=80% \
            --layout=reverse \
            --border=rounded \
            --margin=1 \
            --padding=1 \
            --info=inline \
            --prompt="🔍 Търси команда: " \
            --pointer="▶" \
            --marker="✓" \
            --color="fg:#d0d0d0,bg:#1e1e1e,hl:#5f87af" \
            --color="fg+:#ffffff,bg+:#3a3a3a,hl+:#5fd7ff" \
            --color="info:#af87ff,prompt:#5fd7ff,pointer:#ff5f5f" \
            --color="marker:#87ff00,spinner:#ff87d7,header:#87afaf" \
            --preview='echo -e "\033[1;36mОписание:\033[0m" && echo {} | cut -d"|" -f1 | sed "s/^[ \t]*//" && echo -e "\n\033[1;33mТагове:\033[0m" && echo {} | cut -d"|" -f2 | sed "s/^[ \t]*//" && echo -e "\n\033[1;32mКоманда:\033[0m" && echo {} | sed "s/.*|| //"' \
            --preview-window=right:40%:wrap)
    if [ -n "$selected" ]; then
        local command=$(echo "$selected" | sed 's/.*|| //')
        if grep -qi microsoft /proc/version; then
            echo "$command" | clip.exe
        else
            echo "$command" | xclip -sel clip
        fi
        echo -e "\033[1;32m✓ Копирано:\033[0m $command"
    fi
}
# Добавяне на нова команда
alias cmdadd='_cmdadd() { echo "$1 || $2 || $3" >> ~/.commands.txt && echo "✓ Добавено: $1"; }; _cmdadd'
# Редактиране на файла
alias cmdedit='nano ~/.commands.txt'
# Преглед на всички команди
alias cmdlist='cat ~/.commands.txt | grep -v "^#" | grep -v "^$" | column -t -s "||"'
alias gitmenu='/home/fedia/githelp_menu.sh'
eval "$(starship init bash)"
# --- FZF CUSTOM HISTORY ---
find_history_fzf() {
  local selected_command
  # Използваме --tiebreak=index, за да останат най-новите команди най-отгоре
  selected_command=$(history | fzf --height 40% \
    --layout=reverse --border --ansi \
    --header="📜 История (Ctrl+H) | Най-новите са отгоре" \
    --tiebreak=index \
    --color="header:italic,fg:110,border:93" \
    --preview='echo {}' --preview-window=bottom:3:wrap)
  if [ -n "$selected_command" ]; then
    # Почистваме датата и номера, преди да поставим командата на реда
    local clean_cmd=$(echo "$selected_command" | sed -E 's/^[ ]*[0-9]+[ ]+[0-9]{2}-[0-9]{2}-[0-9]{4} [0-9]{2}:[0-9]{2}:[0-9]{2}[ ]+//')
    READLINE_LINE="$clean_cmd"
    READLINE_POINT=${#READLINE_LINE}
  fi
}
# Свързваме функцията с Ctrl+H
bind -x '"\C-h": find_history_fzf'
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion

5. Разбор на отделните модули

Функцията cmd()

Основната търсачка. При изпълнение прочита ~/.commands.txt и филтрира празните редове и коментарите.

  • Графичен стил: Използва заоблени рамки (--border=rounded) и кастомни цветове за по-добра видимост.
  • Прозорец за преглед (Preview): Панелът вдясно разделя реда по || и визуализира цветно отделните компоненти — описание, тагове, команда.
  • Умно копиране: Проверката grep -qi microsoft /proc/version разпознава WSL и ползва clip.exe. В чист Linux ползва xclip.

Удобни алиаси (Aliases)

  • cmdadd "Описание" "тагове" "команда" — бързо добавя нов ред към ~/.commands.txt директно от терминала.
  • cmdedit — отваря базата данни с nano за бърза редакция.
  • cmdlist — извежда базата данни, подредена в пригледна таблица чрез column.

6. Интелигентна история с Ctrl+H

Освен файла с изпитани команди, функцията find_history_fzf() подобрява работата със стандартната история на Bash.

След обвързването ѝ с Ctrl+H (bind -x '"\C-h": find_history_fzf'), натискането на комбинацията отваря интерактивно меню с историята, където най-новите команди са най-отгоре. При избор, командата се почиства от таймстампа и се зарежда на курсора в терминала.

7. Ежедневен начин на употреба

За да потърсите и копирате команда, просто пишете:

Изпълнение
cmd

Въведете част от описанието или тага, натиснете Enter и командата е копирана в клипборда, готова за поставяне с Ctrl+V или Shift+Insert!

Добавяне на нова команда без да отваряш редактора:

cmdadd
cmdadd "Rsync с прогрес" "rsync,backup" "rsync -avzP source/ dest/"
Необходими пакети: Уверете се, че имате инсталирани fzf и xclip (ако ползвате Linux с GUI):
sudo apt install fzf xclip
Заключение: Тази комбинация от един файл в домашната директория и Bash автоматизация превръща терминала в бърз и подреден асистент. ~/.commands.txt е твоята база — копирай го, споделяй го, възстановявай го след преинсталация.