Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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

share|improve this question

13 Answers 13

up vote 16 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
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
You can skip the first grep by using ifconfig eth0 – Bryan Larsen Dec 1 '14 at 16:29
ifconfig is deprecated, you should use ip address instead – alexises Dec 23 '15 at 15:42
@alexises Yep, I upvoted jsbillings's answer because of that. – l0b0 Dec 23 '15 at 18:35

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
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
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
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
@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

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
share|improve this answer
Oh goodness, thank you for this answer. Never heard of moreutils before. I was seriously considering writing my own little C program to do exactly that. – Chris Harrington Feb 28 at 2:02

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

share|improve this answer
hostname -i gives me just, 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 '15 at 0:07

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 and fe80::/64
  • primary excludes temporary addresses (assuming you want an address that doesn't change)
share|improve this answer
ipa=$(ip route get| grep src| sed 's/.*src \(.*\)$/\1/g')

ipa=$(hostname -i|cut -f2 -d ' ')
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("")));
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 (google's DNS server). It would return something like "" 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

I use this one-liner:

IP=$(/sbin/ifconfig | grep -e "inet:" -e "addr:" | grep -v "inet6" | grep -v "" | 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

Assuming that you may have various interfaces of various name but that you want the first non-localhost one and non-ipv6, you may try:

ip=`ip addr show |grep "inet " |grep -v 127.0.0. |head -1|cut -d" " -f6|cut -d/ -f1`
share|improve this answer
ip=$(ifconfig | grep -oP '(?<=inet addr:)\S*' | grep -v 127) – rcjohnson Nov 17 '15 at 17:12

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,


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 '15 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 ; }' – lakshmikandan Aug 7 '15 at 4:32
hostname -I >> file_name 

this will do everything you want

share|improve this answer
hostname: invalid option -- 'l'... – jasonwryan Dec 23 '15 at 6:56
That's a capital i. Seems to work fine although it apparently prints IP addresses of all interfaces. – Joe Dec 23 '15 at 7:04
it is proposed in one of the previous answers. Also it does not store the IP in the variable. So what is the point of this answer? – Jakuje Dec 23 '15 at 8:10

protected by jasonwryan Dec 23 '15 at 6:59

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

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