Как настроить автодополнение для команды ssh с хостами из .ssh/config
Автодополнение — одна из самых полезных функций командной строки, позволяющая быстро подбирать подходящие аргументы или команды, просто нажав клавишу 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 "
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 "
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.