# ════════════════════════════════════════════════════════════ # Custom Functions # ════════════════════════════════════════════════════════════ # ═══ Навигация ═════════════════════════════════════════════ # mkcd - создать директорию и перейти в неё mkcd() { mkdir -p "$1" && cd "$1" } # up - подняться на N уровней вверх up() { local d="" local limit="${1:-1}" for ((i=1; i<=limit; i++)); do d="../$d" done if [[ -z "$d" ]]; then d=.. fi cd "$d" || return } # ═══ Поиск ═════════════════════════════════════════════════ # ff - быстрый поиск файлов ff() { if command -v fd &>/dev/null; then fd "$@" else find . -iname "*$1*" fi } # fh - поиск в истории команд с fzf fh() { if command -v fzf &>/dev/null; then print -z $(history -n 1 | fzf --tac --no-sort) else history | grep "$1" fi } # ═══ Файлы и директории ════════════════════════════════════ # extract - универсальная распаковка (если плагин не загружен) if ! command -v extract &>/dev/null; then extract() { if [[ -f $1 ]]; then case $1 in *.tar.bz2) tar xjf "$1" ;; *.tar.gz) tar xzf "$1" ;; *.tar.xz) tar xJf "$1" ;; *.bz2) bunzip2 "$1" ;; *.rar) unrar x "$1" ;; *.gz) gunzip "$1" ;; *.tar) tar xf "$1" ;; *.tbz2) tar xjf "$1" ;; *.tgz) tar xzf "$1" ;; *.zip) unzip "$1" ;; *.Z) uncompress "$1" ;; *.7z) 7z x "$1" ;; *) echo "'$1' cannot be extracted via extract()" ;; esac else echo "'$1' is not a valid file" fi } fi # backup - создать резервную копию файла backup() { if [[ -f $1 ]]; then cp "$1"{,.backup-$(date +%Y%m%d-%H%M%S)} echo "Backup created: $1.backup-$(date +%Y%m%d-%H%M%S)" else echo "File not found: $1" fi } # ═══ Размер файлов ═════════════════════════════════════════ # dirsize - показать размер директории dirsize() { du -sh "${1:-.}" 2>/dev/null || echo "Directory not found" } # largest - показать N самых больших файлов в директории largest() { local num=${1:-10} du -ah "${2:-.}" | sort -rh | head -n "$num" } # ═══ Процессы ══════════════════════════════════════════════ # psgrep - поиск процессов psgrep() { ps aux | grep -v grep | grep -i -e VSZ -e "$1" } # kill процесс по имени killp() { local pid pid=$(ps aux | grep -v grep | grep "$1" | awk '{print $2}') if [[ -n $pid ]]; then echo "Killing process: $1 (PID: $pid)" kill -9 "$pid" else echo "Process not found: $1" fi } # ═══ Сеть ══════════════════════════════════════════════════ # myip - показать все IP адреса myip() { echo "External IP: $(curl -s ifconfig.me)" echo "Local IPs:" ip -4 addr show | grep -oP '(?<=inet\s)\d+(\.\d+){3}' | grep -v 127.0.0.1 } # ports - показать открытые порты openports() { sudo netstat -tulanp | grep LISTEN } # ═══ Git ═══════════════════════════════════════════════════ # gitignore - скачать .gitignore для языка gitignore() { if [[ -z $1 ]]; then echo "Usage: gitignore " return 1 fi curl -sL "https://www.toptal.com/developers/gitignore/api/$1" -o .gitignore echo ".gitignore created for: $1" } # gclone - клонировать репозиторий и перейти в него gclone() { if [[ -z $1 ]]; then echo "Usage: gclone " return 1 fi local repo_name=$(basename "$1" .git) git clone "$1" && cd "$repo_name" || return } # ═══ Разработка ════════════════════════════════════════════ # serve - быстрый HTTP сервер serve() { local port="${1:-8000}" if command -v python3 &>/dev/null; then echo "Starting server on http://localhost:$port" python3 -m http.server "$port" else echo "Python3 not found" fi } # json - форматировать JSON json() { if [[ -f $1 ]]; then python3 -m json.tool "$1" else echo "$1" | python3 -m json.tool fi } # ═══ Утилиты ═══════════════════════════════════════════════ # weather - погода для города weather() { local city="${1:-Moscow}" curl -s "wttr.in/$city?format=3" } # Функция для монтирования облаков mount-clouds() { mkdir -p ~/YaDisk ~/GDrive echo "Монтирую диски..." # Яндекс.Диск rclone mount yadisk: ~/YaDisk \ --vfs-cache-mode writes \ --vfs-cache-max-size 10G \ --vfs-cache-max-age 2h \ --allow-non-empty \ --daemon # Google Drive rclone mount gdrive: ~/GDrive \ --vfs-cache-mode writes \ --vfs-cache-max-size 10G \ --vfs-cache-max-age 2h \ --allow-non-empty \ --daemon echo "Готово! Проверяю монтирование:" ls ~/YaDisk >/dev/null 2>&1 && echo "✅ YaDisk смонтирован" || echo "⚠️ Ошибка монтирования YaDisk" ls ~/GDrive >/dev/null 2>&1 && echo "✅ GDrive смонтирован" || echo "⚠️ Ошибка монтирования GDrive" } # Функция для размонтирования unmount-clouds() { echo "Отключаю диски..." fusermount -uz ~/YaDisk 2>/dev/null && echo "✅ YaDisk отключен" || echo "⚠️ YaDisk не был примонтирован" fusermount -uz ~/GDrive 2>/dev/null && echo "✅ GDrive отключен" || echo "⚠️ GDrive не был примонтирован" } SSH_PROXY_PID_FILE="/tmp/ssh_proxy.pid" # Адрес Privoxy, который слушает HTTP и перенаправляет в SOCKS5 # 1. Запуск sshp-start() { if [ -f "$SSH_PROXY_PID_FILE" ] && kill -0 $(cat "$SSH_PROXY_PID_FILE") 2>/dev/null; then echo "Ошибка: Прокси уже запущен (PID: $(cat $SSH_PROXY_PID_FILE))" return 1 fi # Запуск SSH в фоновом режиме ssh -fN -D 127.0.0.1:1080 fl-vps # Сохранение PID последнего запущенного процесса pgrep -f "ssh -fN -D 127.0.0.1:1080 fl-vps" > "$SSH_PROXY_PID_FILE" echo "SSH прокси (SOCKS5) запущен на 127.0.0.1:1080." } # 2. Остановка sshp-stop() { if [ -f "$SSH_PROXY_PID_FILE" ]; then PID=$(cat "$SSH_PROXY_PID_FILE") if kill "$PID" 2>/dev/null; then rm -f "$SSH_PROXY_PID_FILE" echo "SSH прокси (PID $PID) остановлен." else echo "Процесс $PID не найден. Очистка PID-файла..." rm -f "$SSH_PROXY_PID_FILE" fi else echo "Ошибка: Прокси не запущен." fi } # 3. Статус sshp-status() { if [ -f "$SSH_PROXY_PID_FILE" ] && kill -0 $(cat "$SSH_PROXY_PID_FILE") 2>/dev/null; then PID=$(cat "$SSH_PROXY_PID_FILE") echo "Статус: РАБОТАЕТ (PID: $PID)" # Проверка прослушивания порта lsof -i -nP | grep "$PID" | grep LISTEN else echo "Статус: ОСТАНОВЛЕН" fi } sshp-restart() { sshp-stop sleep 1 sshp-start } activate() { local venv_dir="" if [[ -d ".venv" ]]; then venv_dir=".venv" elif [[ -d "venv" ]]; then venv_dir="venv" else for venv_dir in **/.venv **/venv; do [[ -d "$venv_dir" ]] && break done fi if [[ -n "$venv_dir" && -f "$venv_dir/bin/activate" ]]; then source "$venv_dir/bin/activate" else echo "venv/.venv not found" return 1 fi }