views:

236

answers:

3

Context: On *nix systems, one may get the IP address of the machine in a shell script this way:

ifconfig | grep 'inet' | grep -v '127.0.0.1' | cut -d: -f2 | awk '{print $1}'

Or this way too:

ifconfig | grep 'inet' | grep -v '127.0.0.1' | awk '{print $2}' | sed 's/addr://'

Question: Would there be a more straightforward, still portable, way to get the IP address for use in a shell script?

(my apologies to *BSD and Solaris users as the above command may not work; I could not test)

A: 

you give direct interface thereby reducing one grep.

ifconfig eth0 | grep 'inet addr:' | cut -d: -f2 | awk '{print $1}'
coder
Thanks @coder for the suggestion. I wonder whether we cannot go even further though! After all *nix tools do something simple and do it well. So there might be a standard way to get the IP address of an interface. For example, something like `hostname --ip-address` (this does not work) would be great.
Eric Platon
`ifconfig eth0 | grep inet | cut -d: -f2 | cut -d' ' -f1` - this way you do away with heavyweight awk. Of course won't work with ppp0 etc, but if you have more than one NIC you would get more than one answer with your solution too. (head -1 to grab first?)
SF.
+1  A: 

Look here at the Beej's guide to networking to obtain the list of sockets using a simple C program to print out the IP addresses using getaddrinfo(...) call. This simple C Program can be used in part of the shell script to just print out the IP addresses available to stdout which would be easier to do then rely on the ifconfig if you want to remain portable as the output of ifconfig can vary.

Hope this helps, Best regards, Tom.

tommieb75
Thanks Tom for the pointer; it does help. A mine of information. The `showip.c` addresses the problem (removing the output formatting). I wonder though whether there is a way to relying on "standard" *nix tools in shells. For the context, I am writing some scripts that are supposed to work on *nix and *BSD. It works, but my way is not very elegant. Using `showip.c`, I would need to deploy the program together with the script, which I believe may be avoided.
Eric Platon
+1  A: 

you can do it with just one awk command. No need to use too many pipes.

$ ifconfig | awk -F':' '/inet addr/&&!/127.0.0.1/{split($2,_," ");print _[1]}'
ghostdog74
+1, but whitespace is not endangered: use more
glenn jackman
Your proposal is very fine. Simple tests show that it is also faster on average than my basic proposals. I would like to accept yours for now.Portability is not better though, due to `_[1]` and `$2`. For instance, I need to switch the indices under *BSDs (ah, could test it this time).Honestly, I still wonder if there is a tool to get the IP in one-shot, perhaps passing parameters (e.g. interface name). `ifconfig` is indeed to "configure network interface parameters", not get parameters...Perhaps a well-spread version of `showip.c`, as introduced by Tom, would be great.
Eric Platon
if you want to consider portability, you might want to try using a socket library from the various programming tools out there, such as Perl, or Python. eg In Python, one can get the IP address using `socket.gethostbyname(socket.gethostname())`. Of course this is just simple example. Many people have come up with platform independent ways of listing interface address using these libraries. so you might want to give it a try.
ghostdog74
Ghostdob74's latest comment gave me the following idea:`ifconfig | grep -oP "\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b"`It is very portable, as it relies only on standard tools and it does not make any assumption on the position of the IP address in the parsed lines.Note: The regex does capture wrong IP addresses, but it does not matter much given that `ifconfig` returns valid addresses.
Eric Platon