How to edit command completion for ssh on bash?
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
Solution 4
If you are on an Ubuntu Server machine, then you should know that in Ubuntu the entries in ~/.ssh/known_hosts
are hashed, so SSH completion cannot read them. The Canonical devs consider this 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. Based on the links from
Steve Kemp's answer, 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
Solution 5
If you're on a mac you can use Homebrew to install bash-completion:
brew install bash-completion
Add the following to
~/.bash_profile
if [ -f /usr/local/etc/bash_completion ]; then
. /usr/local/etc/bash_completion
fi
If you've installed bash-completion with MacPorts, add this to the bash_profile
if [ -f /opt/local/etc/bash_completion ]; then
. /opt/local/etc/bash_completion
fi
Now you have the package / functionality that Richard Holloway was talking about.
Related videos on Youtube
iconoclast
Contractor at Infinite Red, a mobile app & web site design & development company with employees worldwide, experts in React Native, Rails, Phoenix, and all things JavaScript!
Updated on September 17, 2022Comments
-
iconoclast almost 2 years
(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
- it doesn't use .ssh/config at all
- it requires a username first, even though using .ssh/config makes typing usernames unnecessary
- 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.)
-
Sean the Bean about 8 yearsIf you ended up here looking for a way to exclude hostnames defined in
/etc/hosts
from ssh completion, you can simply addexport COMP_KNOWN_HOSTS_WITH_HOSTFILE=""
to your .bashrc.
-
Powerlord almost 14 years"This is provided by the package bash-completion." Isn't this making an assumption about OS/distribution is being used? I would think FreeBSD would use a different package than Ubuntu Linux, for example.
-
Richard Holloway almost 14 yearsApologies R. Bemrose you are right. I have been jumping between Ubuntu Stack Exchange and Server Fault and you are correct that I assumed the OS is Linux.
-
BiAiB over 12 yearsthanks for this answer. but how can I add a server to the ~/.ssh/config file, I can't find the correct syntax ?
-
Richard Holloway over 12 years@BiAiB: An example from my .ssh/config file is .... : Host nemesis {newline} User richard {newline} Hostname 192.168.1.34 {newline} IdentityFile ~/.ssh/id_rsa. That sort of entry will work. FOr more info check out
man ssh_config
. -
dotancohen over 9 yearsThank you Steve! I was able to use your guide to enable SSH autocompletion in Ubuntu which is an especially problematic system due to known_hosts hashing.