I have a few servers configured in ~/.ssh/config, such as alpha and beta. How might I configure Bash such that the commands ssh al<tab> and scp file.tgz al<tab> autocomplete the names of the configured servers?

I don't want to add the servers to another file (i.e. a Bash array) each time one is added, as we add and remove servers regularly and the list is quite large.

5 Answers
5

It seems 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, the hosts that I am interested in are also found in ~/.ssh/config. Here is a script for Bash Completion that reads the entries from that file:

It seems that in Centos 6 entries in ~/.ssh/known_hosts over-ride entries in ~/.ssh/config eg. if you have foo.bar.baz.com in known_hosts then it will match the whole thing if you do "ssh foo"<tab> - this is undesirable if you have a different user or other settings you want applied from the ssh confg. If you have an entry in ssh config that does not autocomplete properly then check if it is present in known_hosts and delete it. It should now work as normal taking the settings from config.
– Imran-UKApr 18 '16 at 14:46

@Imran-UK: It is known that Ubuntu does not do that sensible thing, under the pretense of security. Apparently the thought is that a malicious entity might, as the user, edit ~/.ssh/config, despite chmod 0600 on the directory. Hey, I wasn't the one who made the decision!
– dotancohenApr 18 '16 at 14:57

1

I use zsh & oh-my-zsh, I just discovered that enabling the "ssh" plugin and putting "HashKnownHosts yes" in my ~/.ssh/config seems to do the right thing. You can change shell whatever the distro so this might be a way around it.
– Imran-UKApr 20 '16 at 9:21

@Imran-UK: In fact I've tried zsh in the past and I do intend on trying it again. I'll look into that. Shukran my friend!
– dotancohenApr 20 '16 at 9:24

I know I'm a little late to the party, but RHEL 7 will autocomplete entries that are in /etc/hosts, other distros may do the same.
– CentimaneJul 25 '16 at 20:23

I'm sorry to be a pain, but even copying the ssh file from that tar archive to /usr/share/bash-completion/completions/ssh doesn't help! Neither does running the complete -W ... command from the Bash prompt. What might be the issue here?
– dotancohenJun 10 '14 at 8:10

Thank you. This does seem to be a known design decision in Ubuntu. Thus I am accepting the answer even though I cannot get bash completion working for ssh or scp.
– dotancohenJun 10 '14 at 9:13

2

Homebrew for OSX also has this: bash-completion and zsh-completions
– Adam NelsonOct 16 '14 at 10:36

Thank you. I've actually already added this directive to ~/.ssh/config and changed the directive in /etc/ssh/ssh_config, and I've removed the ~/.ssh/known_hosts file. After logging into the servers again, the host names are still being saved hashed.
– dotancohenJan 28 '15 at 15:22

I have edited my answer; you will need to specify a host and nest the hash directive inside; I didn't list that as many .ssh/config files will already have this line. Let me know if that works.
– M1keJan 29 '15 at 10:28

This is definitely the easy way to do it! Given that (newer versions of) Ubuntu now have ssh completion enabled, this is probably what is wanted.
– John MontgomerySep 24 '15 at 8:51

As I added below, you can do this, but you probably shouldn't -- you don't need to in order to get completion working anyway. However, if you don't agree and just wanted to un-hash the existing hosts after adding that above, you can just rm ~/.ssh/known_hosts, and that will cause it to be re-generated (un-hashed) whenever you log into a new server.
– Jamieson BeckerJan 8 '18 at 0:31

I noticed it when I realized that only one of the servers I commonly access auto-completed. The only difference between the two was an entry in the ssh config file that was related to authentication. When I added a new entry to the config file for the other server, it started auto-completing too.

Here's the entry for those who were asking:

HOST server-name
GSSAPIAuthentication=no

I would be very surprised if it mattered what you were specifying in the config (as long as it is still valid, of course).

Note that this has nothing at all to do with known_hosts hashing, contrary to what was stated above and the original question. If you wanted to autocomplete from known_hosts, then of course you would have to disable hashing, but that is strongly recommended against.

For example, I have:

Host *
HashKnownHosts yes

in my .ssh/config, and I still have ssh auto-completion working just fine against hosts listed in .ssh/config and /etc/hosts. You do need to add the host to .ssh/config as the OP stated:

Host my-awesome-host
Hostname the.real.host.name

(Or, you can add a host entry to /etc/hosts, which is another source for the Debian/Ubuntu scripts.)

Then, you can just type ssh my-awe<tab> and it will be automagically completed. Again, this is even if you HashKnownHosts, which is highly recommended. (Note that bash completion needs to be enabled in your bash shell, and you need to specifically have those scripts installed as above for your distribution.)

Then, add these lines to your .bashrc to enable it (requires a logout and log back in, or just a new bash typed in to launch a new shell. (You don't need to enable if it's already enabled in /etc/bash.bashrc and /etc/profile sources /etc/bash.bashrc).

if [ -f /etc/bash_completion ]; then
. /etc/bash_completion
fi

This will enable ssh autocompletion (among other things!) from ~/.ssh/config, /etc/hosts, etc.

Note that Debian defaults to ash instead of bash. You can switch to bash easily: