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.
- 807,993
- 194
- 1,674
- 2,175
- 9,859
- 12
- 51
- 59
4 Answers
The bash completion package includes completions for ssh commands, including:
sshssh-addssh-copy-idsshfs
You can browse the source here: https://alioth.debian.org/scm/browser.php?group_id=100114
- 71,734
- 34
- 193
- 226
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,018
- 1
- 15
- 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,494
- 26
- 80
- 116
-
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,397
- 15
- 27
- 31,569
- 7
- 64
- 82
-
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](https://alioth.debian.org/scm/browser.php?group_id=100114), 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