Автодополнение — одна из самых полезных функций командной строки, позволяющая быстро подбирать подходящие аргументы или команды, просто нажав клавишу Tab. В этой статье я расскажу, как настроить автодополнение для команды ssh
, чтобы Bash подсказывал хосты, указанные в файле ~/.ssh/config
.
Шаг 0. Понять зачем это нужно
Иногда клиент для подключения к ssh выдает длинную простыню вида super-puper-host.domain.client.cloud.hosting-provider.org
, порта 3515
и пользователя awesome-protected-user
.
В итоге при подключении на хост через bash надо руками писать что-то вроде
ssh -p 3515 awesome-protected-user@super-puper-host.domain.client.cloud.hosting-provider.org
Что выглядит и воспринимается моим мозгом крайне неудобно. Поэтому я уже давно использую ssh алиасы для этих целей:
Кладу в ~/.ssh/config
строки вида
host client-host HostName super-puper-host.domain.client.cloud.hosting-provider.org User awesome-protected-user Port 3515
После чего я в консоли вбиваю `ssh client-host` и подключаюсь на сервер. Все алиасы, которыми пользуюсь регулярно, вбиваются руками на автомате и это крайне удобно. Но я решил этот процесс сделать еще удобнее, чтобы можно было вбить ssh clie
, нажать TAB и получить варианты для автоматического завершения.
Свои автокомплиты не писал никогда и пришлось много погуглить, чтобы разобраться как это реализовать и подключить у себя на системе. Работаю на Windows 10 и bash запускается через git bash с использованием C:/Users/{username}/
в качестве домашней директории. Внутри wsl подключаюсь только при острой необходимости и избегаю для рядовых админских задач.
Шаг 1. Настройка автодополнения хостов из ~/.ssh/config
По умолчанию Bash предлагает автодополнение файлов и папок для большинства команд, включая ssh
. Чтобы настроить автодополнение хостов, мы используем функцию Bash под названием compgen
, которая позволяет генерировать возможные варианты автодополнения.
Ниже приведен код, который позволяет Bash выводить список хостов, заданных в файле ~/.ssh/config
, при наборе команды ssh
.
Скрипт для автодополнения хостов
Сначала создаем файл ~/.ssh/autocomplete.sh
с содержимым
#!/bin/bash # Функция для автодополнения хостов из файла .ssh/config _ssh_host_autocomplete() { local cur_word # Получаем текущее слово, которое набирается cur_word="${COMP_WORDS[COMP_CWORD]}" # Получаем список всех хостов из .ssh/config local hosts=$(awk '/^[Hh]ost / {print $2}' ~/.ssh/config) # Используем стандартную функцию для автодополнения на основе списка хостов COMPREPLY=($(compgen -W "$hosts" -- "$cur_word")) } # Включаем автодополнение для скрипта complete -o default -o bashdefault -o filenames -F _ssh_host_autocomplete ssh
Как это работает:
-
Функция
_ssh_host_autocomplete_ssh
:-
COMP_WORDS[COMP_CWORD]
— это массив, содержащий все введенные в текущей строке аргументы.COMP_CWORD
— индекс текущего слова. Мы используем это, чтобы получить слово, которое вводится в данный момент. -
awk '/^[Hh]ost / {print $2}' ~/.ssh/config
— с помощью командыawk
мы ищем все строки в файле~/.ssh/config
, которые начинаются сHost
илиhost
, и выводим второй столбец, то есть имя хоста. -
compgen -W "$hosts" -- "$cur_word"
— командаcompgen
используется для создания предложений автодополнения на основе текущего слова и списка хостов. Она выводит подходящие варианты, которые начинаются с введенной строки.
-
-
Команда
complete
:-
-o nospace
— опция указывает не добавлять пробел после автодополнения. Это полезно, чтобы продолжать ввод опций после хоста. -
-F _ssh_host_autocomplete_ssh
— определяет, что для командыssh
используется наша функция автодополнения_ssh_host_autocomplete_ssh
. -
-o default -o bashdefault
— мои тщетные попытки заставить его не предлагать мне файлы из текущей директории, которые начинаются по этому паттерну. Если знаете как это сделать, чтобы работало, то буду признателен.
-
Чтобы проверить работоспособность скрипта пишем source ~/.ssh/autocomplete.sh
, начинаем вводить ssh cli
, жмем TAB и видим магию в виде подсказки автокомплита для быстрого ввода целевого алиаса.
Шаг 2. Автозапуск автокомплита
Теперь дело за малым — прописать в .bashrc
строчку source ~/.ssh/autocomplete.sh
. Теперь этот автокомплит будет работать сразу после запуска системы.
Шаг 3. Добавление удобного алиаса для получения информации о подключении
Иногда нужно передать другому админу информацию о подключении к серверу проекта. Раньше я открывал .ssh/config
руками, искал глазами нужный конфиг, копировал и передавал. После улучшения жизни с автокомплитом сразу захотелось упростить и этот процесс. Сделал так, чтобы можно было написать sshost client-host
и сразу получить содержимое из файла именно по этому хосту.
Создал файл ~/ssh/info.sh
со следующим содержимым:
#!/bin/bash # Скрипт для получения параметров подключения для хостов по регулярному выражению PATTERN=$1 if [ -z "$PATTERN" ]; then echo "Usage: $0 <host-pattern>" exit 1 fi SSH_CONFIG="$HOME/.ssh/config" # Проверяем, существует ли файл .ssh/config if [ ! -f "$SSH_CONFIG" ]; then echo "Error: SSH config file not found." exit 1 fi # Извлекаем все строки для хостов, которые соответствуют переданному регулярному выражению awk -v pattern="$PATTERN" ' tolower($1) == "host" && $2 ~ pattern {found=1; print; next} found && tolower($1) == "host" {found=0} found {print} ' "$SSH_CONFIG"
Внутри .bashrc
добавил в конце alias sshost="bash ~/.ssh/info.sh"
, внутри .ssh/autocomplete.sh
добавил строчку complete -o default -o bashdefault -o filenames -F _ssh_host_autocomplete sshost
, чтобы для этой команды тоже работал автокомплит.
Скрытый текст
~/.ssh/autocomplete.sh
#!/bin/bash # Функция для автодополнения хостов из файла .ssh/config _ssh_host_autocomplete() { local cur_word # Получаем текущее слово, которое набирается cur_word="${COMP_WORDS[COMP_CWORD]}" # Получаем список всех хостов из .ssh/config local hosts=$(awk '/^[Hh]ost / {print $2}' ~/.ssh/config) # Используем стандартную функцию для автодополнения на основе списка хостов COMPREPLY=($(compgen -W "$hosts" -- "$cur_word")) } # Включаем автодополнение для скрипта complete -o default -o bashdefault -o filenames -F _ssh_host_autocomplete sshost complete -o default -o bashdefault -o filenames -F _ssh_host_autocomplete ssh
~/.ssh/info.sh
#!/bin/bash # Скрипт для получения параметров подключения для хостов по регулярному выражению PATTERN=$1 if [ -z "$PATTERN" ]; then echo "Usage: $0 <host-pattern>" exit 1 fi # Путь к файлу .ssh/config (может быть скорректирован, если он в другом месте) SSH_CONFIG="$HOME/.ssh/config" # Проверяем, существует ли файл .ssh/config if [ ! -f "$SSH_CONFIG" ]; then echo "Error: SSH config file not found." exit 1 fi # Извлекаем все строки для хостов, которые соответствуют переданному регулярному выражению awk -v pattern="$PATTERN" ' tolower($1) == "host" && $2 ~ pattern {found=1; print; next} found && tolower($1) == "host" {found=0} found {print} ' "$SSH_CONFIG"
~/.bashrc (добавленные в конце файла строки)
# предыдущее содержимое alias sshost="bash ~/.ssh/info.sh" source ~/.ssh/autocomplete.sh
Дальше перезапускаю bash или выполняю команду source ~/.bashrc
и теперь у меня:
-
при вводе ssh сразу предлагается автокомплит из вариантов алиасов серверов
-
если введу команду sshost, передам алиас то получу в ответ конфиг, который сразу можно передать разработчику
Заключение
С помощью простой настройки автодополнения в Bash вы можете значительно упростить работу с SSH. Теперь, когда вы будете набирать команду ssh
, система предложит только те хосты, которые указаны в файле ~/.ssh/config
, что избавит вас от лишних файловых подсказок и ускорит работу.
Эта настройка идеально подходит для тех, кто часто работает с множеством серверов и хочет ускорить подключение через SSH, избегая ошибок в именах хостов.
Благодарю за внимание и буду рад новыми подписчиками на свой Telegram канал @gmoreva.
ссылка на оригинал статьи https://habr.com/ru/articles/841688/
Добавить комментарий