A colleague just asked me how do I get the IP address of the server this script is running on?, which a great question. You can do it in Python but it's a bit of a hassle and as is often the case, it's really easy to do this in bash. I came up with this off the top of my head. It's not the best way to do it but it works nicely and it's very clear so I figured it would be a nice example to show. (I have a few alternative implementation as well but if you have a neat one I'd love to see it in the comments)

ifconfig |grep "inet addr" |grep -v "127.0.0.1" |awk '{ print $2  }' |cut -d ":" -f 2

What I especially like about it is that it really shows off the approach of combining simple and powerful programs that is at the heart of the UNIX philosophy. So much software today tries to solve every conceivable problem and address every possible use case. In contrast, each of the programs above does a specific job very well and it was up to the user (me, in this case) to put them together to achieve the desired result. If we accept that there should be a learning curve to use software then we can make it much simpler (and thus secure, reliable and enjoyable) by letting the user shoulder some of the burden of the interaction. I'll talk about this in more detail at some point here because it's something that's been on my mind for a while.

So let's run through this step by step.

ifconfig

This command is used to configure your network interfaces. With no arguments it will list information about the interfaces you have connected and part of that information is the IP address! It will typically output something like this:

eth0      Link encap:Ethernet  HWaddr 00:1a:a0:96:5b:cb
          inet addr:192.168.2.162  Bcast:192.168.2.255  Mask:255.255.255.0
          inet6 addr: fe80::21a:a0ff:fe96:5bcb/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:139351 errors:0 dropped:0 overruns:0 frame:0
          TX packets:92329 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:100
          RX bytes:91510049 (91.5 MB)  TX bytes:17897244 (17.8 MB)
          Memory:fdfc0000-fdfe0000

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:10766 errors:0 dropped:0 overruns:0 frame:0
          TX packets:10766 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:7603756 (7.6 MB)  TX bytes:7603756 (7.6 MB)

Your machine have more than one eth adapter and you may have wireless adapters as well. In amongst this information, you can see the IP addresses are listed on lines that start with inet addr:<IP address>. Now we know the format, we can use some UNIX tools to pull it out.

|

The | symbol is read as "pipe" and means "use the ouput of the last command as the input of the next". We use this between each command to refine our result.

grep "inet addr"

This command filters the output from ifconfig. In this case we're saying we only want lines that include inet addr. So this grep command takes the output I have shown above and filters it into something that looks like the following:

          inet addr:192.168.2.162  Bcast:192.168.2.255  Mask:255.255.255.0
          inet addr:127.0.0.1  Mask:255.0.0.0

The next step is to filter this still further.

grep -v "127.0.0.1"

Here I use grep's -v option, which inverts the filtering. In this case, I am saying only consider lines that do not contain 127.0.0.1. I am doing this because 127.0.0.1 is localhost. All computers have this IP address automatically so it isn't that useful to know about this one. I want to exclude this from the output so we only show interesting IP addresses.

We have now filtered the output to the following:

inet addr:192.168.2.162  Bcast:192.168.2.255  Mask:255.255.255.0

Now for the trickiest bit!

awk '{ print $2  }'

awk is a tool for matching and processing patterns in text. Here I'm using it in its simplest form to simply say "print the second field". Fields are automatically created by looking at the spacing and you can see that in this case we have some space then inet then a little space and then adr:192.168.2.162 and so on. We ask awk to give us just that second field, which contains the IP address we are after. An awk command will be applied separately to every line it is given so if we had two IP addresses here, awk would give us the correct field for both.

addr:192.168.2.162

Now we're getting close!

cut -d ":" -f 2

In this last step, we use the cut command to split the input on the : character (the delimiter is specified using -d) and give us the resulting 2nd field (the field is specified with the -f argument. (We could have used awk again but it's nice to see a few different commands at work :) )

192.168.2.162

Great success!

Make a bash alias

I have set this up as an alias so I can type myip from the shell to see my IP address(es). You can do the same by putting this line in your ~/.bash_aliases file or in some other location where it will be run automatically.

alias myip='ifconfig |grep "inet addr" | grep -v "127.0.0.1"| awk '{ print $2  }' | cut -d ":" -f 2'

Enjoy!