I'm trying to create my ~/.ssh/config file for simplify my work life on the server connection.

In Mavericks all worked properly and with the tab I was be able to autocomplete the hostname with file like this:

Host test-host-name
    User root

The same configuration on Yosemite have a different behavior. When I type ssh t on the shell the tab does not autocomplete the hostname.

Do someone know if is something changed in Yosemite and now I need to do something to make it work?


8 Answers 8


You can enable bash shell completion by installing bash-completion via brew:

brew install bash-completion

Then add the following to your ~/.bash_profile:

if [ -f $(brew --prefix)/etc/bash_completion ]; then
. $(brew --prefix)/etc/bash_completion


(Edit: brew tap homebrew/completions is deprecated as of 2018.)

  • 1
    +1 :) When installing bash-completion-1.3.3.high_sierra, it tells me I should add [ -f /usr/local/etc/bash_completion ] && . /usr/local/etc/bash_completion. Could you elaborate on which version (that or yours) should be preferred and why?
    – Jan Nash
    Jun 17, 2018 at 2:41
  • 1
    @JanNash That is basically a single line version of that if above. Additionally the $(brew --prefix) will make it work if your hombrew isn't installing to /usr/local. You should use the version posted as the answer. Dec 7, 2020 at 12:58
  • 2
    This does not work on my M1 Mac. Oct 11, 2021 at 1:55

I assume the shell of your Mac is bash.

You need to complete ssh command, for more detail you can read man complete

_complete_ssh_hosts ()
        comp_ssh_hosts=`cat ~/.ssh/known_hosts | \
                        cut -f 1 -d ' ' | \
                        sed -e s/,.*//g | \
                        grep -v ^# | \
                        uniq | \
                        grep -v "\[" ;
                cat ~/.ssh/config | \
                        grep "^Host " | \
                        awk '{print $2}'
        COMPREPLY=( $(compgen -W "${comp_ssh_hosts}" -- $cur))
        return 0
complete -F _complete_ssh_hosts ssh

Don't forget you need to source the file to get the new command to load in your terminal. or You can put this code in .bash_profile

  • 1
    Yep, the shell is bash. Why in Maveriks I didn't need to do this things?
    – RikyTres
    Jan 20, 2015 at 13:12
  • No, I've tested just now. I can't do that in Mavericks by default.
    – nelson
    Jan 20, 2015 at 13:19
  • comp_ssh_hosts=$(awk -F , 'FNR== NR && ! /^#|\[/ {field = $1} FNR != NR && /^Host / {field = $2} {hosts[field]} END {for (host in hosts) {print host}' "$HOME/.ssh/known hosts" "$HOME/.ssh/config") Jun 27, 2019 at 18:10
  • A quick tip, this command won't find your host if you use tab instead of spaces. So if you are indenting your .ssh/config file, keep an eye to this
    – leoschet
    Mar 30, 2020 at 13:19
  • I get error .bash_profile:21: command not found: complete on M1 Mac Oct 11, 2021 at 2:00

From this article on MacWorld.

Copy/paste the following into ~/.bash_profile:

complete -o default -o nospace -W "$(/usr/bin/env ruby -ne 'puts $_.split(/[,\s]+/)[1..-1].reject{|host| host.match(/\*|\?/)} if $_.match(/^\s*Host\s+/);' < $HOME/.ssh/config)" scp sftp ssh

You'll then need to either restart your terminal or type source ~/.bash_profile (note that the latter will only work in your current tab).


FYI, I'm not sure how to respond directly to nelson's answer since I haven't built up enough reputation to comment on it yet, but on my machine running El Capitan, ^M was being appended to all of the host names from my config file. I had to either add \r to my $IFS variable or remove/substitute all instances of \r from the output of the second cat. In the end, I did the latter by adding tr '\r' '\n' to make that command chain look like this:

cat ~/.ssh/config | \
        grep "^Host " | \
        awk '{print $2}' | \
        tr '\r' '\n'

Nelson's answer (above) doesn't tell you which macOS version he's using.

For macOS 10.14, after installing bash-completion with:

brew install bash-completion

The installer told me to add this line to my .bash_profile (which I put in my .profile instead) and it worked:

  [[ -r "/usr/local/etc/profile.d/bash_completion.sh" ]] && . "/usr/local/etc/profile.d/bash_completion.sh"

If you are using MacPorts:

$ sudo port install bash-completion

Then add the following to your ~/.bash_profile:

if [ -f /opt/local/etc/bash_completion ]; then
    . /opt/local/etc/bash_completion

Existing answers seem like hacks to me. The proper way is to compile OpenSSH with editline/readline/history support, it’s that easy!

Honestly, I cannot possibly fathom WHY any sane person would’ve built it without this, as it gives all the desirable features (up-arrow command history, tab-completion of local and remote filenames, etc.) with zero caveats. I enabled it when I built OpenSSH 8.7p1 on my jailbroken iPad but I'm sure it works equally well anywhere.


You can add entries in /etc/hosts and use them in host name autocomplete:

"ssh @" + [TAB]

Reboot is required for system to reload this file.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .