Привет, Хабр! Сколько раз за день Вы вводите 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), тонкости ОС и инструменты для эффективной работы.
