IP of localhost
There are a fundamental flaws with your question. Firstly, hosts may (and likely will) have more than one address (e.g., multiple interfaces) and even more than one address per interface. This is even more of an issue with IPv6 where every globally connected host as at least two addresses.
Secondly, the "best" way to do this from a shell will vary from system to system.
Linux:
/sbin/ip addr show eth0 | awk -F"[ /]+" '/inet / {print $3}'
>= Solaris 11:
ipadm show-addr net0/v4 | awk -F"[ /]+" '/ok/ {print $5}'
Mac OS X/Darwin:
ipconfig getifaddr en0
Even going lowest common denominator and using ifconfig
won't be consistent because the output format may change. However, to clean up your example, use this:
ifconfig eth0 | awk -F"[ :]+" '/inet / {print $4}'
If you're using a fancier language like perl, ruby, java, etc., instead of the shell, each language will have its own way of obtaining this data from the kernel. I'll leave finding this up to you.
The information can change at any time, so it needs to be retrieved from the kernel, it can't be stored in a file.
There is no really nice way to obtain this information. Your parsing is as good as any, except that hard-coding the second line is wrong: there is no guarantee that the interfaces will be listed in any particular order. It is fairly common for a machine to have more than one interface: you may have multiple network cards, or virtual interfaces.
Often, the IP address you're interested in is the one associated with the default route. With most configurations, you can obtain the right interface with the route
command, then extract the IP address of that interface with ifconfig
.
/sbin/ifconfig $(/sbin/route -n |
awk '$1 == "0.0.0.0" {print $8}') |
awk 'match($0, /inet addr:[.0-9]+/) {print substr($0, RSTART+10, RLENGTH-10)}'
Note that there is no need to call sudo
. ifconfig
and route
are often not in the default PATH
for non-root users, but you can use them with no special privilege as long as you're only reading information and not changing the settings.
On unix variants other than Linux, you may have to tweak the commands above. Most have commands called ifconfig
and route
, but the output format may be different.
Under Linux, instead of ifconfig
and route
, you can use the ip
command from the iproute2 tool suite. While the authors of iproute2 consider ifconfig
and route
to be deprecated, there is in fact little advantage to using ip
, since the output of ip
is not markedly easier to parse, and ifconfig
and route
are always available whereas some stripped-down Linux installations omit ip
.
All the answers here are technically correct, but they're not what I would consider the "right" answer. Unfortunately, your question is extremely vague (which I can understand if you're not really good with how networking in Linux works), so I'll give some answers to possible interpretations of the question.
The machine's primary IP
The machine has one IP above all others which is considered the machines primary IP. Note though that this is pretty meaningless, as a box can have multiple IPs and which one gets used varies (I'll get into this in a bit).
The primary IP is simply the IP associated with the machine's hostname. You can find this IP by running the following
getent hosts "$(hostname)" | awk '{ print $1 }'
Now, what this does is looks up the IP for the machine's hostname according to /etc/nsswitch.conf
. In most cases, the /etc/nsswitch.conf
file contains hosts: files dns
. This means that when trying to do any sort of hostname or address lookups, it will look in /etc/hosts
first, and then consult DNS (as configured by /etc/resolv.conf
).
So the command getent hosts "$(hostname)"
will likely grab the matching entry from /etc/hosts
. The awk
simply just grabs just the IP out of that line.
(getent
is just a simple utility for querying 'databases' listed in /etc/nsswitch.conf
)
The IP used to communicate with the outside world
As I mentioned earlier, the machine's primary IP is fairly meaningless. The machine can use any of multiple IPs for communication. In your case, you likely just have one interface and one (non-localhost) IP. However a server can have multiple interfaces or IPs (sometimes multiple IPs on a single interface).
Which IP gets used is determined by the kernel's routing table. I'm not going to get into the specifics of how the routing table works as its not simple (there's multiple routing tables, and which one gets used is dependent upon table selection rules). I'll just tell you how to find which IP would get used.
To find out which IP will be used to communicate with a specific destination, use the following command:
ip route get 1.2.3.4
(with 1.2.3.4
being the IP of the destination)
On my machine, if I do this with one of google.com's IPs (74.125.139.102
), I get the following:
74.125.139.102 via 192.168.0.1 dev wlan0 src 192.168.0.24
cache
What this tells me is that the IP 192.168.0.24
will be used whenever my machine goes to talk to 74.125.139.102
.
If you want just the IP, you can just throw an extra grep
on the end.
ip route get 1.2.3.4 | grep -oP '(?<=src )\S+'
grep
is used instead of an awk
because it's less prone to error. It's possible the line may change in which the IP won't be in the same place, but it will always follow "src", so we just grab the value immediately after "src"
Default gateway IP
Lastly, there's the default gateway. If you don't have a specific destination to query to see which IP will be used, you can pick the one from the default gateway. If you only have one interface, this is all that'll matter anyway.
This is basically the exact same thing as above, just using the default gateway as our destination to look up
ip route get "$(ip route show to 0/0 | grep -oP '(?<=via )\S+')"
This will give you a line like the one in the above section. The src
value is the IP that will be used for traffic flowing through the default gateway.
As in the previous section, to get just the IP, add a grep
.
ip route get "$(ip route show to 0/0 | grep -oP '(?<=via )\S+')" | grep -oP '(?<=src )\S+'