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.


Zsh completion works with so called ssh bookmarks. These are per host configurations in ~/.ssh/config.

For example,

  host baz
    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.


I am using the completion script from ohmyzsh:


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
  • I don't use zsh but bash... – Gilles Quenot Oct 5 '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 5 '12 at 21:17

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


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:

    local cur prev opts
    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!

  • 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 1:36
  • @nhed: Thank you! I did not know that was allowed. – dotancohen May 22 '15 at 7:31

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).

  • 4
    I'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 5 '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 Quenot Oct 5 '12 at 20:56
  • See my extended answer, I am using completion from ohmyzsh. – kwarrick Oct 5 '12 at 21:05
  • 1
    If 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 5 '12 at 21:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.