Alias is silver, function() is gold!


Everyone who has reached the first advancement of any meaningful martial arts, know that in order to get that first level you need to learn some very basic, yet useful techniques.

Being a unix admin is the same. The more tools you know, and the more you know how to put them together, the fancier the belt to keep your trousers up will be.

I sometimes claim to be a black belt unix admin; or at least I was once upon the time. Some people might disagree, but after almost 20 years of hacking around I think I know my way around. I have Niklas to thank for my yellow belt, since he lent me my a Sun SPARCstation 2 so that I could cram in the basics of Solaris after accepting a job offer. It helped, after which I practiced a lot to get better.

Now over to this post.

Everyone who claims to know anything about UNIX/Linux/OSX knows about alias. It is very useful to simplify commands you use a lot. I often use it to manage ssh connections for customers.

I.e, in my .bash_profile, I have an alias for each customer I am working for at the moment:

[cc] alias set_custA=". ~/.aliases.custA"

alias set_custB=". ~/.aliases.custB"

alias set_kmg=". ~/.aliases.kmggroup"

[/cc] Every time I start a new terminal window, and if I would like to work for i.e my own company, I would type set_kmg, which would source the alias file ~/.aliases.kmggroup, which could look like this:

[cc] alias op5-v001fry="ssh malu@"

alias guran="ssh malu@"

[/cc] This is decently ok, but there is one drawback; aliases does not accept any paramters. I.e, I could not do a:

[cc] guran ls -la

[/cc] At least not if I expect it to resolve to "ssh malu@ ls -la". And I often have a wish to do so. Or to do something more complex. But this will serve as a good example.

So, how do I solve this, then? Enter: function()

function() beats alias in any cage match there ever will be. Bash has a wonderful implementation of functions which you can use in all it's glory. I will use guran again to show how to implement this. Another good example I have is for one customer where I sometimes want to do the same thing on multiple servers, as root. But let's start with guran. I would put this in my ~/.aliases.kmggroup file next to the aliases.

[cc] function guran(){

ssh malu@ "$@"


[/cc] Voilla!

Again, if I would like to use my example of the multiple hosts:

[cce] function sshAll(){ hosts="100 101 102 103 104"

for host in $hosts do

echo "Host: $host" 1>&2

ssh -t malu@10.0.0.$host "$@" done }

[/cce] Using this script I could, for example, edit /etc/hosts on these five hosts by issuing "sshAll sudo vi /etc/hosts".

That's it, for today!


Edit: Fredrik Roubert just mentioned that I should change the functions to "ssh xxx xxx $@" from $* to better handle parameters with spaces. Thanks!

Edit2: Fredrik came back to me, pointing out that there is a difference between $@ and "$@", which there of course is. He was not sure about the implications in bash, since he is a zsh guy, but I made this quick hack as an example:


[cce lines="-1"] malu@KMG-Hotspot.local:/Users/malu/test $cat functions function mother(){ echo Parameter 1: $1 echo Parameter 2: $2 echo Parameter 3: $3 echo Parameter 4: $4 } function function1(){ mother $@ }

function function2(){ mother "$@" } malu@KMG-Hotspot.local:/Users/malu $function1 "parameter 1" "parameter 2" Parameter 1: parameter Parameter 2: 1 Parameter 3: parameter Parameter 4: 2 malu@KMG-Hotspot.local:/Users/malu $function2 "parameter 1" "parameter 2" Parameter 1: parameter 1 Parameter 2: parameter 2 Parameter 3: Parameter 4: