First of all, I generated a list of bash aliases with entries like the following:
...
alias 123='ssh user@192.168.0.123'
alias 125='ssh user@192.168.0.125'
...
But this solution looked too ugly. Another solution was to add lots of ssh_config entries as described here; it was ugly too.
Another thing that made these two hacks useless was that I needed to connect to hosts in other networks, like 192.168.1.x, 192.168.20.x etc, and it wasn't possible to add all of them to .bash_aliases or ~/.ssh/config.
So I invented the wheel.
In Debian (and Ubuntu too) there is a valuable addendum to bash: function command_not_found_handle that accepts the name of non-existing command and decides what to do: call another program instead this command or something else. By default, it searches the command name in apt package cache and advices user to install the appropriate package.
I wrote my own function and placed it to ~/.bashrc:
command_not_found_handle () {
if [[ ! "$1" ]] ; then
return 127
fi
n="$1"
if echo $n| perl -ne 'exit(/^([1-9]|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])$/ ? 0:1)' ; then
ip=192.168.20.$n
elif echo $n| perl -ne '
exit (/^([1-9]|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])\.
([1-9]|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])
$/x ? 0:1)' ; then
ip=192.168.$n
elif echo $n| perl -ne '
exit (/^([1-9]|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])\.
([1-9]|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])\.
([1-9]|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])\.
([1-9]|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])
$/x ? 0:1)' ; then
ip=$n
else
return 127
fi
ssh $ip
}
How does it work. The function analyzes its argument, and if this argument is a number from 0 to 255, it calls "ssh 192.168.0.xx" (where xx is the argument passed to this function); if the argument passes contains two dot-separated numbers like xx.xx (each is from 0 to 255), it calls ssh 192.168.xx.xx. If the argument validates as a correct IP-address, "ssh ip" is called. In any other cases, exit code 127 is returned and bash handles "command not found" error by itself.
So, I write only the last number of the IP address and it automatically being translated to the full IP:
bvk@host ~$ 15
# becomes ssh 192.168.0.15
bvk@host ~$ 29
# becomes ssh 192.168.0.29
bvk@host ~$ 10.51
# becomes ssh 192.168.10.51
bvk@host ~$ 172.19.4.10
# becomes ssh 172.19.4.10
Also, I wrote some entries to ~/.ssh/config to specify different parameters for different hosts:
Host 192.168.20.251
User special_user1
Host 192.168.20.252
User special_user2
Host 192.168.20.254
User special_user3
Host *
User ordinary_user
This allows me to connect to the hosts 192.168.20.251, 192.168.20.252 and 192.168.20.253 as respective users, and to all other hosts as ordinary_user.
P.S. It's often impossible to give names to all the hosts in our networks, because hosts in our test environment go up and down frequently. So we have to connect to them via their IPs.
No more linux!
ReplyDeleteOhmigod. I can't understand a sole word. Author please return to Russian and to philosophy. A want another "Gorden as a aberrated mirror of our time" or something like that.
Thank you for this interesting tip but I do not want to remember all the IPs of servers I have to connect to.
ReplyDeleteI'd rather prefer to use the /etc/hosts & .ssh/config files.
Regards.
Brilliant, great tip! Thank you very much.
ReplyDeletefor i in {1..255}
ReplyDeletedo
alias $i="ssh user@192.168.0.$i"
done
Ben, you rock.
Delete