How to edit command completion for ssh on bash?

(I've asked this question regarding zsh, but I also use bash and would find it useful there too--as I'm guessing many others would too since bash has many more users than zsh.)

I'd like to set up command completion on bash to display host names after I type

ssh [TAB]

taking the names out of my .ssh/config file (and preferably from known_hosts and /etc/hosts and anywhere else that makes sense) and presenting one single list.

It does some of this currently, but

  1. it doesn't use .ssh/config at all
  2. it requires a username first, even though using .ssh/config makes typing usernames unnecessary
  3. it presents multiple lists (probably one from known_hosts and another from /etc/hosts, but I haven't verified that)

So I want to be include known usernames as well as known hostnames in the (preferably single) list after typing ssh [TAB]

(I'm coming here before Google because 1) it'll result in the answer getting stored here, and 2) it's probably more efficient. If no one else answers, I'll hunt down the answer.)


Solution 1:

I wrote this two part guide a while ago:

http://www.debian-administration.org/article/316/An_introduction_to_bash_completion_part_1

http://www.debian-administration.org/article/317/An_introduction_to_bash_completion_part_2

It explains how you can write completion scripts - though as the previous answer indicates what you want should be already available to you.

Solution 2:

This functionality is already provided by bash completion. The actual file if you want to edit its functionality is /etc/bash_completion.d/ssh.

This is provided by the package bash-completion.

On typing ssh < TAB > it will list all hosts in /etc/hosts and ~/.ssh/config in one list.

If you have the User specified for a given host you don't need to specify this when using ssh.

So if you want to ssh to server brandon

Type ssh br< TAB > and it should autocomplete the word brandon as long as that host is in either /etc/hosts or ~/.ssh/config.

Solution 3:

This is what I have in my .bashrc for ssh hostname completion :

SSH_COMPLETE=( $(cut -f1 -d' ' ~/.ssh/known_hosts |\
                 tr ',' '\n' |\
                 sort -u |\
                 grep -e '[:alpha:]') )
complete -o default -W "${SSH_COMPLETE[*]}" ssh