Привет, Хабр! Сколько раз за день Вы вводите cd ~/projects/current-project/src/components/very-long-folder-name, чтобы просто перейти в нужную директорию? Такая навигация в терминале отнимает кучу времени и сил, теряется фокус. В этой статье хочу поделиться простым bash-скриптом, который покажет Вам пронумерованный список избранных папок и позволит переходить в них одной цифрой.

Введение

Работа в терминале - удобство и контроль, но постоянное переключение между 2-3 проектами и глубокими вложенными папками зачастую превращается в рутину. Поиск в истории команд, автодополнение или нескончаемые ls и cd - все это мелочи, которые вместе раздражают, отвлекают и отнимают время.

В этой статье мы создадим свой инструмент для быстрой навигации на чистом bash, никаких зависимостей не требуется. В итоге у Вас будет лишь функция для .bashrc (или .zshrc), которая по одной команде откроет меню с Вашими наиболее частыми путями и мгновенно перенесёт в выбранную директорию.

Определяем список избранных папок

Функция строится на обычном bash-массиве. Это основа нашего скрипта.

Откроем файл конфигурации вашей оболочки. Обычно это ~/.bashrc или ~/.zshrc.

nano ~/.bashrc

Добавим в конец файла массив с путями к Вашим директориям, которые используются чаще всего. Замените пути на свои.

# CD Menu (быстрая навигация по папкам)
CD_MENU_LIST=(
  "/home/user/projects/current-web-app"
  "/home/user/projects/legacy-project"
  "/home/user/Downloads"
  "/var/log"
  "/home/user/documents/notes"
)
  • Мы создаем централизованный список, который можно в любой момент отредактировать. Массив идеально подходит для этой задачи, так как позволяет легко обращаться к элементам по индексу (номерам).

Пишем основную логику меню

Теперь, сразу после объявления массива, добавим функцию, которая будет работать с этим списком.

cdm() {
  local -a menu_items=("${CD_MENU_LIST[@]}")
  local item

  # Показываем меню
  echo "Куда переходим?"
  for i in "${!menu_items[@]}"; do
    printf "%2d) %s\n" $((i+1)) "${menu_items[i]}"
  done

  # Ждем ввод
  read -p "Введите номер: " choice

  # Проверяем, что ввод корректен
  if [[ ! "$choice" =~ ^[0-9]+$ ]] || [ "$choice" -lt 1 ] || [ "$choice" -gt "${#menu_items[@]}" ]; then
    echo "Ошибка: неверный номер." >&2
    return 1
  fi

  # Выполняем переход
  cd "${menu_items[$((choice-1))]}"
  echo "Перешел в: ${menu_items[$((choice-1))]}"
}

Что тут происходит:

  • local -a menu_items...: создаем локальную копию массива внутри функции. Это необходимо, чтобы избежать случайных изменений глобальной переменной.

  • for i in "${!menu_items[@]}": цикл по индексам массива, а не по элементам. Это позволяет нам получить и номер, и значение.

  • printf "%2d) %s\n" ...: форматированный вывод с выравниванием номеров. %2d гарантирует, что однозначные числа займут два символа, и список не "поедет".

  • $((i+1)): показываем числа с 1, а не с 0, так как это интуитивно понятнее.

  • Регулярное выражение ^[0-9]+$ и последующие проверки (-lt, -gt) - это защита от некорректного ввода. Без них ввод буквы или несуществующего номера приведет к ошибке.

  • cd "${menu_items[$((choice-1))]}": поскольку массив индексируется с 0, а нам понятнее вводить числа с 1 - вычитаем единицу. Это основной момент всей логики.

Далее следует только сохранить изменения в файле и применить командой:

source ~/.bashrc

Команда source заставляет текущую оболочку перечитать файл конфига и выполнить его. Без этого функция cdm будет не доступна.

Результат и проверка

Всё готово. После ввода команды:

cdm

Мы увидим вывод с нашими путями:

Куда переходим?
 1) /home/user/projects/current-web-app
 2) /home/user/projects/legacy-project
 3) /home/user/Downloads
 4) /var/log
 5) /home/user/documents/notes
Введите номер:

Введём, например, 3, нажмём Enter. Если всё сделано корректно, мы окажемся в папке ~/Downloads, а в терминале появится сообщение: Перешёл в: /home/user/Downloads.

Демонстрация работы
Демонстрация работы

Итоговый код в ~/.bashrc целиком:

# CD Menu (быстрая навигация по папкам)
CD_MENU_LIST=(
  "/home/user/projects/current-web-app"
  "/home/user/projects/legacy-project"
  "/home/user/Downloads"
  "/var/log"
  "/home/user/documents/notes"
)

cdm() {
  local -a menu_items=("${CD_MENU_LIST[@]}")
  local item

  echo "Куда переходим?"
  for i in "${!menu_items[@]}"; do
    printf "%2d) %s\n" $((i+1)) "${menu_items[i]}"
  done

  read -p "Введите номер: " choice

  if [[ ! "$choice" =~ ^[0-9]+$ ]] || [ "$choice" -lt 1 ] || [ "$choice" -gt "${#menu_items[@]}" ]; then
    echo "Ошибка: неверный номер." >&2
    return 1
  fi

  cd "${menu_items[$((choice-1))]}"
  echo "Перешел в: ${menu_items[$((choice-1))]}"
}

Заключение

Всего за 10 минут создаётся очень простой и полезный инструмент, который поможет автоматизировать рутинную часть работы в терминале. Переключение между проектами значительно упрощается и экономит достаточно много времени на переходах между директориями.

P. S. В моей группе в Телеграмм разбираем практические кейсы: скрипты (Python/Bash/PowerShell), тонкости ОС и инструменты для эффективной работы.

Комментарии (7)


  1. Semy
    21.10.2025 15:14

    Интересно, но есть zoxide. Она умеет прикидываться cd и даже запоминать ничего не надо. Зато переход можно делать даже по уникальным частям имен:
    :~> cd log
    :/var/log> cd down
    :/home/user/Downloads> cd legacy
    :/home/user/projects/legacy-project>


  1. Shaman_RSHU
    21.10.2025 15:14

    Можно просто

    git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf

    ~/.fzf/install

    Добавить в ~/.zshrc

    [ -f ~/.fzf.zsh ] && source ~/.fzf.zsh

    И просто ходить по каталогам по Alt+C используя нечёткий поиск


  1. SlavaRejik
    21.10.2025 15:14

    А можно алиасами наплодить команд, типа cd1, cd2 итд. Но запомнить, за какой цифрой какая директория.


  1. nerudo
    21.10.2025 15:14

    Вот примерно за это я и люблю синие панельки - что без всякой головной боли получаю быструю навигацию по каталогам-файлам с историей


  1. gybson_63
    21.10.2025 15:14

    флэшбэки

    [MENU] MENUITEM=EMS MENUITEM=XMS MENUITEM=Windows [COMMON] DEVICE=C:\DOS\HIMEM.SYS [EMS] DEVICE=C:\DOS\EMM386.EXE [XMS] [Windows]


    1. uckuH
      21.10.2025 15:14

      +1 *Пустил скупую мужскую слезу*


  1. mcsimm
    21.10.2025 15:14

    Far2L с меню по F2