Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

How can I get my own IP address and save it to a variable in a shell script?

share|improve this question

10 Answers 10

up vote 8 down vote accepted

It's not so easy if you want to take into account wlan and other alternative interfaces. If you know which interface you want the address for (e.g., eth0, the first Ethernet card), you can use this:

ip="$(ifconfig | grep -A 1 'eth0' | tail -1 | cut -d ':' -f 2 | cut -d ' ' -f 1)"

In other words, get me the network configuration information, look for eth0, get that line and the next one (-A 1), get only the last line, get the second part of that line when splitting with :, then get the first part of that when splitting with space.

share|improve this answer
1  
I added an additional grep to your code to ignore any interface with "eth0:" in it; this now works as I expect (giving only the "eth0" IP address and not any sub-interfaces (eth0:0, eth0:1, etc.): ip="$(ifconfig | grep -v 'eth0:' | grep -A 1 'eth0' | tail -1 | cut -d ':' -f 2 | cut -d ' ' -f 1)" –  user32250 Feb 12 '13 at 19:49
1  
You can skip the first grep by using ifconfig eth0 –  Bryan Larsen Dec 1 '14 at 16:29

I believe the "modern tools" way to get your ipv4 address is to parse 'ip' rather than 'ifconfig', so it'd be something like:

ip=$(/sbin/ip -o -4 addr list eth0 | awk '{print $4}' | cut -d/ -f1)

or something like that.

share|improve this answer
    
How common is /sbin/ip? I don't have it on any of my computers –  Michael Mrozek Mar 3 '11 at 15:03
4  
ip is available on all the Red Hat and Fedora distros I've used. ip is part of the iproute2 package (linuxfoundation.org/collaborate/workgroups/networking/iproute2). ifconfig and route are supposedly deprecated, although they continue to be used by a lot of people, particularly in scripts. ip is much more parsable, in my opionion. –  jsbillings Mar 3 '11 at 15:13
3  
ip is also available on all Debian and Debian based distros I've seen. It's part of the iproute package which is marked as important. –  Arrowmaster Mar 3 '11 at 23:43
2  
This is absolutely how it should be done, I would downvote the other answers for their use of ifconfig. ip is part of the iproute2 package which is many a distro by default. It's in most good repos to. en.wikipedia.org/wiki/Iproute2 –  jwbensley Sep 15 '12 at 12:13
1  
@jsbillings Why /sbin/ip instead of ip? –  l0b0 Jan 15 '13 at 13:02

If you want the address of an interface, the easiest way is to install moreutils then:

anthony@Zia:~$ ifdata -pa br0
172.16.1.244

ifdata answers pretty much every question you'd be tempted to parse ifconfig output for.

If you want to find out your IP address as the outside sees it (beyond any NAT, etc.), there are plenty of services that'll do it. One is fairly easy:

anthony@Zia:~$ curl ifconfig.me
173.167.51.137
share|improve this answer

Why not simply do IP=$(hostname -I) ?

share|improve this answer
    
hostname -i gives me just 127.0.0.1, hostname -I gives me the correct IP-Adress... –  student Sep 15 '12 at 12:41
    
@student yes indeed, I have tested it on a machine that has can resolve its hostname, as the manpage says -i Display the network address(es) of the host name. Note that this works only if the host name can be resolved. Avoid using this option; use hostname --all-ip-addresses –  Andrei Sep 15 '12 at 12:49
    
How can I configure my machine to resolve its hostname? –  student Sep 15 '12 at 12:58
    
the easiest way is adding it to /etc/hosts, along with the corresponding IP address –  Andrei Sep 16 '12 at 10:06
    
No -I on FreeBSD, but you can use dig +short `hostname -f` –  Tigger Jun 3 at 0:07

I use this one-liner:

IP=$(/sbin/ifconfig | grep -e "inet:" -e "addr:" | grep -v "inet6" | grep -v "127.0.0.1" | head -n 1 | awk '{print $2}' | cut -c6-)

Uses ifconfig (widely available), does not take localhost address, does not bind you to a given interface name, does not take into account IPv6 and tries to get the IP of the first network interface available.

share|improve this answer

Depends what you mean by own IP address. Systems have IP addresses on several subnets (sometimes several per subnet), some of which IPv4, some IPv6 using devices like ethernet adapters, loopback interfaces, VPN tunnels, bridges, virtual interfaces...

I you mean the IP address by which another given device may reach your computer, you have to find out which subnet that is, and which version of IP we're talking about. Also, bear in mind that because of NAT performed by firewall/routers, the IP address of an interface may not be the same as a remote host sees an incoming connection from your computer coming from.

When there is fancy source routing or per protocol/port routing it can be difficult to find out which interface would be used to talk to one remote computer over a given protocol and even then, there's no guarantee that the IP address of that interface may be directly addressable by the remote computer wanting to establish a new connection to your computer.

For IPv4 (probably works for IPv6 as well), a trick that works in many unices including Linux to find out the IP address of the interface used to reach a given host is to use a connect(2) on a UDP socket and use getsockname():

For instance, on my home computer:

perl -MSocket -le 'socket(S, PF_INET, SOCK_DGRAM, getprotobyname("udp"));
connect(S, sockaddr_in(1, inet_aton("8.8.8.8")));
print inet_ntoa((sockaddr_in(getsockname(S)))[1]);'

Would be used to find out the IP address of the interface via which I would reach 8.8.8.8 (google's DNS server). It would return something like "192.168.1.123" which is the address of the interface for the default route to the internet. However, google wouldn't see a DNS request from my machine as coming from that IP address which is a private one, as there's NAT performed by my home broadband router.

connect() on a UDP socket doesn't send any packet (UDP is connection-less), but prepares the socket by querying the routing table.

share|improve this answer

To get IPv4 and IPv6 addresses, and not assume the main interface is eth0 (these days em1 is more common), try:

ips=$(ip -o addr show up primary scope global |
      while read -r num dev fam addr rest; do echo ${addr%/*}; done)
  • -o uses the one-line output format, which is easier to process with read, grep, etc.
  • up excludes devices that aren't active
  • scope global excludes private/local addresses such as 127.0.0.1 and fe80::/64
  • primary excludes temporary addresses (assuming you want an address that doesn't change)
share|improve this answer

I needed to do this within an alias to start a radio server on my wired NIC. I used

ip addr | egrep -i "inet.+eth1" | awk -F[\ /] '{print $6}' | tr -d [:space:]
share|improve this answer

On FreeBSD you can use

dig +short `hostname -f`

This may work for other environments, depends on your set-up.

share|improve this answer

Some commands are working on centos 6 or 7, the below command working on both,

#!/bin/sh

serverip=`/sbin/ifconfig eth0 | grep "inet" | awk '{print $2}' | awk 'NR==1' | cut -d':' -f2`

echo $serverip
share|improve this answer
    
that's way too much grep | awk | awk . line can be shortened to /sbin/ifconfig eth0 | awk '$1 == "inet" { print substr($2,6); next ; } ' –  Archemar Aug 6 at 11:23
    
I accepted, can you check both centos6 and 7?. centos 7.x /sbin/ifconfig eth0 | awk '$1 == "inet" { print substr($2,6); next ; }' 35.104.41 centos6.x (Working fine) /sbin/ifconfig eth0 | awk '$1 == "inet" { print substr($2,6); next ; }' 192.168.0.1 –  lakshmikandan Aug 7 at 4:32

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.