Привет, Хабр! Сколько раз за день Вы вводите 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)

Shaman_RSHU
21.10.2025 15:14Можно просто
git clone --depth 1https://github.com/junegunn/fzf.git~/.fzf~/.fzf/installДобавить в ~/.zshrc
[ -f ~/.fzf.zsh ] && source ~/.fzf.zshИ просто ходить по каталогам по Alt+C используя нечёткий поиск

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

nerudo
21.10.2025 15:14Вот примерно за это я и люблю синие панельки - что без всякой головной боли получаю быструю навигацию по каталогам-файлам с историей
Semy
Интересно, но есть zoxide. Она умеет прикидываться cd и даже запоминать ничего не надо. Зато переход можно делать даже по уникальным частям имен:
:~> cd log
:/var/log> cd down
:/home/user/Downloads> cd legacy
:/home/user/projects/legacy-project>