Traincoding: SSH aliases

It’s been a while since I published a traincoding snippet. Here’s a small one for your .bashrc that creates ‘alias host=ssh host’ for all hosts you know. It helps if you disable HashKnownHosts in your ~/.ssh/config.

if [ -d ~/.ssh ]; then

    # Touch files we expect to exist
    if [ ! -e ~/.ssh/config ]; then touch ~/.ssh/config; fi
    if [ ! -e ~/.ssh/known_hosts ]; then touch ~/.ssh/known_hosts; fi

    # Parse ~/.ssh/known_hosts and ~/.ssh/config to find hosts
    for x in `sed -e ’s/[, ].*//’ ~/.ssh/known_hosts; awk ‘/^Host [^*?]+$/{print $2}’ ~/.ssh/config`; do

        # Don’t override commands
        type $x > /dev/null 2>&1 && continue
        alias $x=”ssh $x”

        # Remove the domainname
        y=${x/.*/}
        if [ "$y" != "$x" ]; then
            if ! type $y > /dev/null 2>&1; then
                alias $y=”ssh $x”
            fi
        fi

        # Remove prefix. Add prefixes you want removed here
        y=${y/pf1-/}
        y=${y/pf2-/}
        if [ "$y" != "$x" ]; then
            if ! type $y > /dev/null 2>&1; then
                alias $y=”ssh $x”
            fi
        fi
    done
fi

If you add this to your ~/.bashrc, the following will be done when you start a shell:

alias pf1-foo.bar.com=”ssh pf1-foo.bar.com”
alias pf1-foo=”ssh pf1-foo.bar.com”
alias foo=”ssh pf1-foo.bar.com”

This helps a lot if you connect to a lot of machines with names like annoyingprefix-machine1.annoyingly.long.domain.name (Guess what I need to connect to often :))

It checks whether a command with a certain name exists already, so it won’t do things like alias svn=”ssh svn.gnome.org” which would be annoying.

6 Comments

  1. ephemient Says:

    See man 5 ssh_config for a nicer solution:

    $ cat ~/.ssh/config
    Host shortname
    HostName some.really.long.hostname
    User username_that_i_never_remember
    $ ssh shortname # == ssh username_that_i_never_remember@some.really.long.hostname

    Works regardless of your shell, and scp/sftp recognize the shortnames as well.

  2. Sam Says:

    Great script! I made some mods that you might like (and I hope pre works!):

    #!/bin/bash
    shopt -s extglob
    isint(){
    case $1 in
    ?([-+])+([0-9]) )
    return 0;;
    *) return 1;;
    esac
    }

    if [[ -d ~/.ssh ]]; then

    # Touch files we expect to exist
    if [[ ! -e ~/.ssh/config ]]; then touch ~/.ssh/config; fi
    if [[ ! -e ~/.ssh/known_hosts ]]; then touch ~/.ssh/known_hosts; fi

    # Parse ~/.ssh/known_hosts and ~/.ssh/config to find hosts
    for x in `sed -e ’s/[, ].*//’ ~/.ssh/known_hosts; awk ‘/^Host [^*?]+$/{print $2}’ ~/.ssh/config`; do

    # Don’t override commands
    type “${x}” > /dev/null 2>&1 && continue

    # Remove the domainname
    y=${x%%.*}
    # you don’t want IP addresses for aliases, trust me.
    isint $y && continue

    # If it’s a short-name, move on
    #z=${x##*.}
    #[[ "${z}" == 'edu' || "${z}" == 'com' || "${z}" == 'net' ]] || continue
    # So the above is commented out because you’d be surprised at how much you rely on your search path
    # You should pipe the output of this script to sort and your fqdn’s will override your shorts.
    echo alias “${x}”=”ssh $x”

    if [[ "$y" != "$x" ]]; then
    if ! type $y > /dev/null 2>&1; then
    echo alias $y=”ssh $x”
    fi
    fi
    done
    fi

  3. ephemient: That’s unmaintainable for hundreds of hosts :) My .ssh/config is fairly short, uses lots of wildcards and ProxyCommands.

  4. ephemient Says:

    Hmm, my .ssh/config has a stanza for every host I’ve ever accessed more than once, I don’t see why it’s unmaintainable.

    But the lack of the ability to do something like
    Host foo-%1
    HostName foo-%1.bar.baz.bam
    does make me sad.

  5. Malcolm Parsons Says:

    bash can do hostname completion.

    $ export HOSTFILE=~/hostnames
    $ cat $HOSTFILE
    example.com
    me.homelinux.org
    http://ftp.isp.com
    $ ssh
    example.com http://ftp.isp.com me.homelinux.org
    $ ssh e
    $ ssh example.com

  6. The bash-completion package has much better completion for ssh/scp etc, including remote filename completion for scp and rsync :)

Leave a Comment