Pick of the Week - Nov 10 [Show all picks]
Path Finder 5 - A feature-laden Finder replacement
Submit Hint Search The Forums LinksStatsPollsFAQHeadlinesRSS
12,000 hints and counting!

Create on-the-fly hostname lists for ssh tab completion UNIX
If you don't want to manage server lists for tab completion with ssh, put the following line in your .bash_profile file in your home directory: This will allow you to tab complete any hostname you've previously ssh'd to.

[robg adds: This worked as described for me. The complete command is a built-in bash function that lets you specify lists of options to be used with tab completion on a given command. The version above parses your known_hosts to create the list of options. You can read more about the complete built-in function in the bash man pages -- man bash, then search for the section titled Programmable Completion.]
    •    
  • Currently 0.00 / 5
  • 1
  • 2
  • 3
  • 4
  • 5
  (0 votes cast)
 
[8,881 views]  

Create on-the-fly hostname lists for ssh tab completion | 19 comments | Create New Account
Click here to return to the 'Create on-the-fly hostname lists for ssh tab completion' hint
The following comments are owned by whomever posted them. This site is not responsible for what they say.
Implications For sudo Command
Authored by: bfad on Mon, Mar 24 2008 at 8:15AM PDT
One of the most frustrating things for me is that commands don't tab-complete when prefixed by sudo, but now I can modify this for the sudo command. Does anyone with better Unix knowledge then me know how I could use this to read in my $PATH variable to get the list of directories for sudo to look under for tab completion? Otherwise I'll just have to add all the paths individually, including the one's I've specified.

[ Reply to This | # ]
Implications For sudo Command
Authored by: ccase on Mon, Mar 24 2008 at 12:04PM PDT
Try: complete -c -f command sudo

[ Reply to This | # ]
Implications For sudo Command
Authored by: bfad on Tue, Mar 25 2008 at 10:40AM PDT
Thank you ccase! That works perfectly.

[ Reply to This | # ]
Any way to use the with ssh/config aliases.
Authored by: drudus on Mon, Mar 24 2008 at 8:37AM PDT
It would be great to use this with the aliases in the ssh config, any suggestions?

D

[ Reply to This | # ]
Create on-the-fly hostname lists for ssh tab completion
Authored by: manly on Mon, Mar 24 2008 at 9:04AM PDT

Or better yet, install the bash-completion package from macports and then add the following to your .bashrc:

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

This gives a variety of neat additions, including ssh, ping, ftp, tar, etc.



[ Reply to This | # ]
Create on-the-fly hostname lists for ssh tab completion
Authored by: thegooch49 on Mon, Mar 24 2008 at 9:24AM PDT
Any way to make this work with tcsh? I tried this in my .tcshrc, and I got an error of an 'illeagal variable'.

[ Reply to This | # ]
Create on-the-fly hostname lists for ssh tab completion (TCSH)
Authored by: joab on Mon, Mar 24 2008 at 3:45PM PDT
Enter this into your .tcshrc:

set hosts = `sed -e 's/^ *//' -e '/^#/d' -e 's/[, ].*//' -e '/\[/d' ~/.ssh/known_hosts | sort -u`
complete ssh 'p/1/$hosts/' 'p/2/c'

It completes first hosts and then commands.

[ Reply to This | # ]
Create on-the-fly hostname lists for ssh tab completion
Authored by: pauldy on Mon, Mar 24 2008 at 9:33AM PDT
Worked great for me but only for servers already in the list, is there a way to make this evaluate everytime you press tab?

[ Reply to This | # ]
Create on-the-fly hostname lists for ssh tab completion
Authored by: BobHarris on Mon, Mar 24 2008 at 9:05PM PDT
I do not know how to directly make completion re-evaluate known_hosts for every TAB, but maybe this is the next best thing.

If you put the following code in your .bashrc (or .bash_profile; where ever you setup your PS1 prompt variable), then after each command when the prompt is output, the known_hosts file will be checked to see if has been modified, and if so, it will be re-evaluated:

update_hosts_complete()
{
    typeset ref=/tmp/hosts_complete.$$
    typeset khosts=$HOME/.ssh/known_hosts

    if [[ $khosts -nt $ref ]]; then
        touch $ref
        complete -W "$(awk -F'[, ]' '
            $1 !~ /[/ {hosts[$1]=1}
            END{
                for(host in hosts)
                    printf(" %s", host)
            }' $khosts)" ssh
    fi
}
PS1="$(update_hosts_complete) your prompt goes here> "

Bob Harris

[ Reply to This | # ]

Create on-the-fly hostname lists for ssh tab completion
Authored by: Nem on Mon, Mar 24 2008 at 9:34AM PDT
The macports suggestion is a good one, but IMO, includes too much. If you don't have macports installed, you can add the following to your .bash_profile (I wouldn't add it to my .bashrc, since that gets read in by cron jobs and remote commands).

There are a couple improvements here. First, this will also read in aliases in your ~/.ssh/config file. Secondly, it will ignore commented out entries in your ~/.ssh/known_hosts file. Finally, this is a function and not a static list. Thus, it is immediately aware of any new additions to either file (although on really slow machines it will be slower than a static list).


_complete_ssh_hosts ()
{
        COMPREPLY=()
        cur="${COMP_WORDS[COMP_CWORD]}"
        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


---
Nem W. Schlecht
http://geekmuse.net/

[ Reply to This | # ]

Create on-the-fly hostname lists for ssh tab completion
Authored by: leono on Mon, Mar 24 2008 at 11:05AM PDT
Nice job, Nem! I don't actually have a ~/.ssh/config file, so here's a modification to deal with that situation:

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


[ Reply to This | # ]
Create on-the-fly hostname lists for ssh tab completion
Authored by: slswift on Mon, Mar 24 2008 at 7:34PM PDT
Thanks for the slick inclusion of .ssh/config. However, I had to make a quick tweak to 'awk' out the 3rd entry rather than the 2nd.

awk '{print $3}'

My .ssh/config uses this syntax, which may or may not be 'standard', but definitely works. My config syntax comes from ssh v. 1, so the current accepted syntax could be VASTLY different.

Host = solutions


[ Reply to This | # ]
Create on-the-fly hostname lists for ssh tab completion
Authored by: ssevenup on Mon, Mar 24 2008 at 6:37PM PDT
tcsh and/or zsh versions? I actually would find the aliases in config more useful than known_hosts I think? My user name is rarely the same on the box I'm logging into.

---
Mark Moorcroft
ELORET Corp. - NASA/Ames RC
Sys. Admin.

[ Reply to This | # ]
Create on-the-fly hostname lists for ssh tab completion
Authored by: edaominoratto on Mon, Mar 24 2008 at 10:49AM PDT
Does anyone know how to get complete to work case insensitive?

I have set completion-ignore-case On (in .inputrc), but what I define to get completed remains case sensitive.

Example: When I use complete -W "Foo" ls, then ls f[TAB] doesn't return a result (while ls F[TAB] does).

[ Reply to This | # ]
Create on-the-fly hostname lists for ssh tab completion
Authored by: CarlRJ on Mon, Mar 24 2008 at 1:53PM PDT
For what it's worth, the core bit of the process:
cat ~/.ssh/known_hosts | cut -f 1 -d ' ' | sed -e s/,.*//g | uniq | grep -v "\["
can be reduced from five commands and four pipe to two commands and one pipe:
sed -e 's/^  *//' -e '/^#/d' -e 's/[, ].*//' -e '/\[/d' ~/.ssh/known_hosts | sort -u
This also handles comment lines in known_hosts (starting with "#") and duplicates which do not follow each other (by using "sort -u" in place of "uniq").

[ Reply to This | # ]
Create on-the-fly hostname lists for ssh tab completion
Authored by: corienti on Mon, Mar 24 2008 at 4:00PM PDT
VERY nice, CarlRJ! I am impressed - and you got rid of a classical "useless use of cat" as well! Sed is a beautiful thing...


[ Reply to This | # ]
zsh
Authored by: adrianm on Mon, Mar 24 2008 at 11:28PM PDT
If you use zsh (IMO, the best interactive shell), you not only get completion on hosts, but also on known usernames (and it adds the @ after them).

Just put:

autoload -U compinit
compinit

in your .zshrc

---
~/.sig: not found

[ Reply to This | # ]
zsh
Authored by: ssevenup on Tue, Mar 25 2008 at 6:55PM PDT
Thanks oodles man :-)

---
Mark Moorcroft
ELORET Corp. - NASA/Ames RC
Sys. Admin.

[ Reply to This | # ]
Create on-the-fly hostname lists for ssh tab completion
Authored by: nevstokes on Tue, Mar 25 2008 at 2:26AM PDT
Or you could just use reverse-i-search for autocompletion of anything in your bash history.

Hit control+r and start typing

[ Reply to This | # ]