47

Want to get the IP address using Shell script. Without knowing the eth0 or eth1 or eth2 How to get the particular IP address.

I am not interest to get localhost address, want to get private IP address.

Beginner
  • 1,960

3 Answers3

69

You can do :

ip addr | grep 'state UP' -A2 | tail -n1 | awk '{print $2}' | cut -f1 -d'/'

which gives you the first private IP address listed in ip addr.

For example, with ip addr, I get:

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: em1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:16:76:de:c1:f1 brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.85/24 brd 192.168.0.255 scope global dynamic em1
       valid_lft 42505sec preferred_lft 42505sec
    inet6 fe80::216:76ff:fede:c1f1/64 scope link 
       valid_lft forever preferred_lft forever
3: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    link/ether 52:54:00:da:92:d0 brd ff:ff:ff:ff:ff:ff
    inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
       valid_lft forever preferred_lft forever
4: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast master virbr0 state DOWN group default qlen 500
    link/ether 52:54:00:da:92:d0 brd ff:ff:ff:ff:ff:ff

With the commandline before, I get 192.168.0.85 which is the IP address of em1.

To put it in a variable inside a shell script, you can do var=$(ip addr | grep 'state UP' -A2 | tail -n1 | awk '{print $2}' | cut -f1 -d'/'). Now, until the end of the script, $var will have the value of the IP address.

lgeorget
  • 13,914
  • And indeed, it's very similar to http://unix.stackexchange.com/questions/8518/how-to-get-my-own-ip-address-and-save-it-to-a-variable-in-a-shell-script?rq=1. I did not look for duplicates before posting... – lgeorget Mar 12 '14 at 07:54
  • ip addr | grep 'state UP' -A2 | tail -n1 | awk '{print $2}' | cut -f1 -d'/' using this command i got private address. Now i want assign the output to a variable – Beginner Mar 12 '14 at 08:07
  • @rajcoumar I updated the answer. Note that this question had already been asked and answered on this site. See http://unix.stackexchange.com/questions/4569/storing-output-of-command-in-shell-variable for details. – lgeorget Mar 12 '14 at 08:12
  • Note also that my answer is not of the most elegant. There may be a better way to do this than parsing the output of ip addr. – lgeorget Mar 12 '14 at 08:13
  • ip addr | grep 'state UP' -A2 | tail -n1 | awk -F'[/ ]+' '{print $3}' this works too, by the way – lgeorget Oct 12 '15 at 08:56
  • code ip addr | awk ' BEGIN { state=0 } { if ($0 ~ /state/) { if ($0 ~ /state UP/) { state=1 } else { state=0 } } if (state == 1 && $1 ~ /inet/) { if ($2 !~ /^127/ && $2 !~ /^::/) { split($2, ip, "/") print ip[1] } } } ' code – kerolasa Mar 10 '16 at 10:20
  • I use this to get IP of interface ppp0: /sbin/ip a s ppp0 | grep inet | awk '{print $2}' – martin Jan 23 '18 at 13:54
40

To list all IP addresses, regardless of name, try this:

ifconfig | perl -nle 's/dr:(\S+)/print $1/e'

or:

ifconfig | awk '/inet addr/{print substr($2,6)}'

Specify the interface name (e.g. eth0) right after ifconfig if you only want the IP of a specific interface:

ifconfig eth0 | perl -nle 's/dr:(\S+)/print $1/e'

or:

ifconfig eth0 | awk '/inet addr/{print substr($2,6)}'
cuonglm
  • 153,898
  • thanks, this is my output 192.168.56.102 10.192.1.218 10.0.2.15 127.0.0.1, Now i want to take 10.192.1.218 and assign into new varible in shell script. how we can do ? – Beginner Mar 12 '14 at 07:48
  • that would just display the IP addresses.. it would be better if the corresponding interface names like eth0, eth1,... are displayed too. :) – rusty Mar 12 '14 at 07:50
  • Absolutely use the routing tables as @ymattw suggests! This has the wonderful property of returning exactly the address through which your computer is configured to talk to the given address. I think you probably want awk '{print $NF; exit}', though, to get the last field (source address) of the first row. – 10gistic Aug 22 '16 at 19:11
  • 8
    Thanks for pointing out, looks like my last edit wasn't saved. Interesting, I couldn't edit my own answer, so just repost:

    ip route get 1.1.1.1 | awk '{print $NF; exit} # this get the ip of the interface which can reach to outside

    – ymattw Aug 23 '16 at 23:20
10

Flagrant copy paste from stackoverflow since we can't dupe across sites. I know it's not bash or sh, but who doesn't have python installed at this point anyway?

You should use netifaces. It is designed to be cross-platform on Mac OS X, Linux, and Windows.

>>> import netifaces as ni
>>> ni.interfaces()
['lo', 'eth0', 'eth1', 'vboxnet0', 'dummy1']
>>> ni.ifaddresses('eth0')
{17: [{'broadcast': 'ff:ff:ff:ff:ff:ff', 'addr': '00:02:55:7b:b2:f6'}], 2: [{'broadcast': '24.19.161.7', 'netmask': '255.255.255.248', 'addr': '24.19.161.6'}], 10: [{'netmask': 'ffff:ffff:ffff:ffff::', 'addr': 'fe80::202:55ff:fe7b:b2f6%eth0'}]}
>>> 
>>> ni.ifaddresses.__doc__
'Obtain information about the specified network interface.\n\nReturns a dict whose keys are equal to the address family constants,\ne.g. netifaces.AF_INET, and whose values are a list of addresses in\nthat family that are attached to the network interface.'
>>> # for the IPv4 address of eth0
>>> ni.ifaddresses('eth0')[2][0]['addr']
'24.19.161.6'

The numbers used to index protocols are from /usr/include/linux/socket.h (in Linux)...

#define AF_INET         2       /* Internet IP Protocol         */
#define AF_INET6        10      /* IP version 6                 */
#define AF_PACKET       17      /* Packet family                */

End copy paste

If all you want is the IP of the up and outbound interface, this works.

Yet ANOTHER option if you just want to enumerate over up interfaces, since nobody seems to be able to understand exactly what you want:

import netifaces as ni
ints = ni.interfaces()
for i in ints:
  if 'eth' in i:
    try:
      ni.ifaddresses(i)[2][0]['addr']
      print("interface: " + i)
      print("address: " + ni.ifaddresses(i)[2][0]['addr'])
    except:
      pass
  elif 'wlan' in i:
    try:
      ni.ifaddresses(i)[2][0]['addr']
      print("interface: " + i)
      print("address: " + ni.ifaddresses(i)[2][0]['addr'])
    except:
      pass
RobotHumans
  • 1,492
  • 1
    Note that the OP stated in his question that it doesn't know in advance which interface is UP. He just wants the IP addr of the interface in state "up" without knowing which one it is. – lgeorget Mar 12 '14 at 08:29
  • Then it's just getting the local address from an open socket to Google. The way I read it, he wanted to enumerate over all interfaces and map IPs to interfaces as opposed to just opening a socket and looking for the local IP. – RobotHumans Mar 12 '14 at 08:31
  • Added a simple script to address the "just give me the outbound IP" problem. – RobotHumans Mar 12 '14 at 08:36
  • He doesn't want his external address but his private address. The way I understand it, he could be connected to a private network by any of his interfaces and just wants to know his private IP address without knowing which interface is used. – lgeorget Mar 12 '14 at 08:42
  • The private address would still be given by the second script, it's just the outbound private address. – RobotHumans Mar 12 '14 at 08:59