I have big list of servers which I normally ssh
to all the time. Is there any way using bash
or zsh
so that I can keep the list of hostname and bash auto-completion goes through the file and gives me suggestion for the boxes starting with those letters whenever I type the first few letters of the hostname.

- 829,060

- 9,959
4 Answers
The bash completion package includes completions for ssh
commands, including:
ssh
ssh-add
ssh-copy-id
sshfs
You can browse the source here: https://alioth.debian.org/scm/browser.php?group_id=100114

- 73,126
Zsh
completion works with so called ssh bookmarks. These are per host configurations in ~/.ssh/config
.
For example,
host baz
hostname 192.168.1.2
port 22
user warrick
host bar
hostname example.com
port 2200
user kevin
identityfile /home/warrick/.ssh/ec2.pem
man ssh_config
to see a full list of options.
EDIT
I am using the completion script from ohmyzsh:
https://raw.github.com/robbyrussell/oh-my-zsh/master/lib/completion.zsh
In similiar style to ohmyzsh
, I placed the above script into ~/.zsh/libs/completion.zsh
and added this to ~/.zshrc
.
# ~/.zshrc
for f in ~/.zsh/libs/*; do
source $f
done

- 3,128
- 1
- 16
- 10
-
I don't use zsh but bash... – Gilles Quénot Oct 05 '12 at 21:12
-
Right, the OPs question is for bash or zsh, my comment on your post was simply to favor ~/.ssh/config to /etc/hosts if at all possible, which as per his question is possible when using zsh. – kwarrick Oct 05 '12 at 21:17
Copied from my own answer on unix.SE:
If you are on an Ubuntu host, then you should know that in Ubuntu the entries in ~/.ssh/known_hosts
are hashed, so SSH completion cannot read them. This is a feature, not a bug. Even by adding HashKnownHosts no
to ~/.ssh/config
and /etc/ssh/ssh_config
I was unable to prevent the host hashing.
However, you can read the configured entries from ~/.ssh/config
, which are not hashed. Here is a script for Bash Completion that reads the entries from that file:
_ssh()
{
local cur prev opts
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
opts=$(grep '^Host' ~/.ssh/config | awk '{print $2}')
COMPREPLY=( $(compgen -W "$opts" -- ${cur}) )
return 0
}
complete -F _ssh ssh
Put that script in /etc/bash_completion.d/ssh
and then source it with the following command:
$ . /etc/bash_completion.d/ssh
I found this guide invaluable and I would not have been able to script this without it. Thank you Steve Kemp for writing that terrific guide!

- 15,864
-
2+1 but I would replace the awk line with
opts=$(grep '^Host' ~/.ssh/config | sed 's@^Host @@')
because the~/.ssh/config
syntax allows for multiple names on a single line – nhed May 22 '15 at 01:36 -
For this to work, put any hosts you want to complete in your /etc/hosts
file.
You need also bash-completion
package (containing file /etc/bash_completion and directory /etc/bash_completion.d)
and source it in ~/.bashrc (. /etc/bash_completion
- sometimes it's commented out in /etc/bash.bashrc or in ~/.bashrc).

- 1,463
- 17
- 28

- 33,867
-
4I'd recommend against using /etc/hosts. Instead add so called ssh bookmarks in ~/.ssh/config.
man ssh_config
for more details, but it is far more versatile allowing you to specify multiple aliases, username, port, and much much more. – kwarrick Oct 05 '12 at 20:52 -
With archlinux, when I put something in
/etc/ssh/ssh_config
, I have no completion working for the configured hosts. – Gilles Quénot Oct 05 '12 at 20:56 -
-
1If you look at the source, you will see that the script checks
known_hosts
as well as the other config files, eg.,~/.ssh/config
– jasonwryan Oct 05 '12 at 21:21