How to configure autocompletion for ssh command with hosts from .ssh
Autocompletion is one of the most useful features of the command line, allowing you to quickly find the appropriate arguments or commands by simply pressing the Tab key. In this article, I will tell you how to set up autocompletion for a command ssh
so that Bash will suggest hosts specified in the file ~/.ssh/config
.
Step 0. Understand why it is necessary
Sometimes the client for connecting to ssh gives a long sheet of the form super-puper-host.domain.client.cloud.hosting-provider.org
port 3515
and the user awesome-protected-user
.
As a result, when connecting to a host via bash, you need to manually write something like
ssh -p 3515 awesome-protected-user@super-puper-host.domain.client.cloud.hosting-provider.org
Which looks and feels extremely awkward to my brain. That's why I've been using Alice's ssh for these purposes for a long time now:
I put it in ~/.ssh/config
lines of the form
host client-host
HostName super-puper-host.domain.client.cloud.hosting-provider.org
User awesome-protected-user
Port 3515
After that, I type `ssh client-host` into the console and connect to the server. All the aliases that I use regularly are entered manually automatically, and this is extremely convenient. But I decided to make this process even more convenient, so that I could enter ssh clie
press TAB and get auto-complete options.
I have never written my own autocompletes and had to google a lot to figure out how to implement this and connect it to my system. I work on Windows 10 and bash is launched via git bash using C:/Users/{username}/
as a home directory. Inside wsl I connect only when absolutely necessary and avoid it for routine admin tasks.
Step 1: Configure host autocompletion from ~/.ssh/config
By default, Bash offers file and folder completion for most commands, including ssh
To set up host autocompletion, we use a Bash function called compgen
which allows you to generate possible auto-completion options.
Below is the code that allows Bash to list hosts specified in a file ~/.ssh/config
when typing a command ssh
.
Script for autocompletion of hosts
First, create a file ~/.ssh/autocomplete.sh
with content
#!/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
How does this work:
Function
_ssh_host_autocomplete_ssh
:COMP_WORDS[COMP_CWORD]
— is an array containing all the arguments entered in the current line.COMP_CWORD
— the index of the current word. We use this to get the word that is currently being typed.awk '/^[Hh]ost / {print $2}' ~/.ssh/config
– using the commandawk
we search for all lines in the file~/.ssh/config
which start withHost
orhost
and we display the second column, that is, the host name.compgen -W "$hosts" -- "$cur_word"
– teamcompgen
is used to generate autocomplete suggestions based on the current word and a list of hosts. It outputs matching suggestions that start with the entered string.
Team
complete
:-o nospace
— option specifies not to add a space after autocompletion. This is useful to continue entering options after the host.-F _ssh_host_autocomplete_ssh
– defines what is for the teamssh
our autocomplete feature is used_ssh_host_autocomplete_ssh
.-o default -o bashdefault
– my futile attempts to make it not offer me files from the current directory that start with this pattern. If you know how to make this work, I would be grateful.
To check the functionality of the script, we write source ~/.ssh/autocomplete.sh
we start entering ssh cli
press TAB and see the magic in the form of an autocomplete hint for quickly entering the target alias.
Step 2. Autostart autocomplete
Now all that's left to do is register it in .bashrc
line source ~/.ssh/autocomplete.sh
. Now this autocomplete will work immediately after the system starts.
Step 3: Add a convenient alias to get connection information
Sometimes you need to pass information about connecting to the project server to another admin. I used to open .ssh/config
with my hands, looking for the necessary config with my eyes, copying and transferring. After improving my life with autocomplete, I immediately wanted to simplify this process. I made it so that I could write sshost client-host
and immediately get the contents from the file on this host.
Created file ~/ssh/info.sh
with the following contents:
#!/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"
Inside .bashrc
added at the end alias sshost="bash ~/.ssh/info.sh"
inside .ssh/autocomplete.sh
added a line complete -o default -o bashdefault -o filenames -F _ssh_host_autocomplete sshost
so that autocomplete works for this command too.
Hidden text
~/.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 (added at the end of the line)
# предыдущее содержимое
alias sshost="bash ~/.ssh/info.sh"
source ~/.ssh/autocomplete.sh
Then I restart bash or execute the command source ~/.bashrc
and now I have:
when entering ssh, autocomplete from server alias options is immediately offered
if I enter the sshost command and pass the alias, I will receive a config in response, which I can immediately pass to the developer
Conclusion
With a simple Bash autocompletion setup, you can make working with SSH much easier. Now, when you type a command ssh
the system will offer only those hosts that are specified in the file ~/.ssh/config
which will save you from unnecessary file prompts and speed up your work.
This setup is ideal for those who frequently work with multiple servers and want to speed up SSH connections while avoiding hostname errors.
Thank you for your attention and I will be glad to have new subscribers to my Telegram channel @gmoreva.