19

I want to edit the bashrc file to have a simple function called "myip" to run. As you might guess, the function myip prints only my internal IP address of my machine.

The far as I got working, this is the script:

ifconfig en1 | awk '{ print $2}' | sort

Which got my this output:

10.0.0.12
options=1<PERFORMNUD>
flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST>
fe80::daa2:5eff:fe96:ba2f%en1
d8:a2:5e:96:ba:2f
autoselect
active

I'm working on Mac OS X.

How can I get this done?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Fernando Retimo
  • 1,003
  • 3
  • 13
  • 25
  • 3
    Which OS? Which ifconfig? – Tripp Kinetics May 29 '14 at 13:28
  • 2
    `ifconfig en1 | sed -n '/inet addr/s/.*addr.\([^ ]*\) .*/\1/p'` Works on ubuntu, fedora at least... Based on your `ifconfig en1` output, you can tweak more if required. – anishsane May 29 '14 at 13:29
  • 1
    `/sbin/ifconfig $1 | grep "inet addr" | awk -F: '{print $2}' | awk '{print $1}'`. Defined the location as it isnt normally in users `PATH` except for root –  May 29 '14 at 13:48

20 Answers20

27

Both the following work here (CentOS 5).

ip addr show eth0 | awk '$1 == "inet" {gsub(/\/.*$/, "", $2); print $2}'

ifconfig eth0 | awk '/inet addr/ {gsub("addr:", "", $2); print $2}'

For OS X (v10.11 (El Capitan) at least):

ifconfig en0 | awk '$1 == "inet" {print $2}'
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Etan Reisner
  • 77,877
  • 8
  • 106
  • 148
24

This is the more "agnostic" way to get the IP address, regardless of you *nix system (Mac OS, Linux), interface name, and even your locale configuration:

ifconfig | grep -E "([0-9]{1,3}\.){3}[0-9]{1,3}" | grep -v 127.0.0.1 | awk '{ print $2 }' | cut -f2 -d:

If you have more than one active IP, will listed each one in a separated line. If you want just the first IP, add | head -n1 to the expression:

ifconfig | grep -E "([0-9]{1,3}\.){3}[0-9]{1,3}" \
     | grep -v 127.0.0.1 | awk '{ print $2 }' | cut -f2 -d: | head -n1

And if you want the IP address of a specific interface, replace the first expression ifconfig by ifconfig INTERFACENAME, for example ifconfig eth0 | grep -E ... .

Finally, you noticed that one of the things the script does is to omit the IP 127.0.0.1 called by sysadmins and developers "localhost", but take into account that some applications may also add virtual network devices with an IP that may be the one returned if is not added to the omit list, eg. Docker adds a virtual interface docker0 that usually has the IP 172.17.0.1, if you want to omit this IP along with the "localhost" one, change the expression grep -v 127.0.0.1 to take into account the another IP. In this case (omit localhost and docker) the final expression will be:

ifconfig | grep -E "([0-9]{1,3}\.){3}[0-9]{1,3}" | grep -v '[127.0|172.17].0.1' | awk '{ print $2 }' | cut -f2 -d: | head -n1

These are some examples mentioned in this page that fails in some circumstances and why:

  • ip route ...: the ip command isn't installed in OSX machines.
  • hostname -I: the -I option is invalid in OSX.
  • ifconfig en0 ...: the interfaces names (eth0, en0) are different in Linux and OSX, and in Linux the name depends also of the interface type (ethX for ethernet connection, wlanX for wireless, etc.).
  • python -c 'import socket; print(socket.gethostbyname(socket.gethostname()))': this got me 127.0.1.1 (a loopback IP) in Ubuntu Linux 14.04, so doesn't work.
  • ifconfig | grep 'inet addr:' | grep -v 127.0.0.1 | head -n1 | cut -f2 -d: | cut -f1 -d ' ': the Geograph's post is the more close, but doesn't work in some Linux distributions without LANG=en configured, because the text inet addr: that grep looks for is output with a different text in other locales, and in Mac OS that label is also different.
Mariano Ruiz
  • 4,314
  • 2
  • 38
  • 34
12

In case of eth0, the following works for me. Try to tweak it with the same logic.

ifconfig eth0 | grep 'inet addr:' | cut -d: -f2 | awk '{ print $1}'  
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Devesh
  • 2,024
  • 2
  • 16
  • 21
  • 5
    Since I am awk-phobic, I have a slightly different version: `ifconfig eth0 | grep "inet\ addr" | cut -d: -f2 | cut -d" " -f1` – Ivan X May 29 '14 at 13:53
  • Does not work on Mac OSX ... The reason is that the syntax of the ifconfig is a bit different. Thanks though. – Fernando Retimo May 29 '14 at 15:17
  • There is a similar post on so. Hope this helps! http://stackoverflow.com/questions/7181998/how-to-get-an-output-formatted-as-interface-ip-address-from-ifconfig-on-mac – Devesh May 29 '14 at 15:37
8

Well, after hours of struggling I finally got it right:

ifconfig en1 | awk '{ print $2}' | grep -E -o "([0-9]{1,3}[\.]){3}[0-9]{1,3}"

That last part I had missing is just grep a pattern of IP addresses from my list.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Fernando Retimo
  • 1,003
  • 3
  • 13
  • 25
  • 2
    this will do it for you too: ifconfig en1|awk '/inet / {print $2}' – Dave Apr 12 '15 at 17:05
  • I would argue this isn't the best option as it infers the you always know the device. If it changes etc, you will get an error "error fetching interface information: Device not found" – Mike Q Dec 05 '18 at 15:23
7

You can use awk to do both the selecting of the inet line and the parsing of the IP address like so:

$ ip addr ls docker0 | awk '/inet / {print $2}' | cut -d"/" -f1
172.17.42.1

In the example above, substitute the device handle eth0 in for docker0. Also, if you want a pure AWK implementation, you can do the "cutting" within like so:

$ ip addr ls docker0 | awk '/inet / {split($2, ary, /\//); print ary[1]}'
172.17.42.1
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
slm
  • 15,396
  • 12
  • 109
  • 124
7

IPv4 Examples using BASH4+

Example 1, using hostname:

  hostname -I|cut -d" " -f 1

Example 2, the device is known (and it never changes) :

  ifconfig ens5 | grep "inet" | awk '{print $2}' |  sed 's/[^0-9.]*//g'

Example 3, don't now the device (e.g. eth0, eth1, enp0s23, or wpxxx) :

 ip a | awk 'BEGIN{ "hostname -I|cut -d\" \" -f 1" | getline ip} $2 ~ ip {print "Device: "$NF "  IP: "$2}'

Example 4, want the network IP address:

 wget -q -O /dev/stdout http://checkip.dyndns.org/ | cut -d":" -f2 | cut -d \< -f1

enjoy.

Mike Q
  • 6,716
  • 5
  • 55
  • 62
3

There is another easy way to get the IP address apart from parsing ifconfig.

hostname -I -I, --all-ip-addresses all addresses for the host -i, --ip-address addresses for the hostname

Ref: http://linux.die.net/man/1/hostname

Example:

[ec2-user@terraform ~]$ hostname -I
10.10.10.10

Baskar
  • 1,439
  • 12
  • 17
2

No need to do unportable ifconfig parsing in Bash. It's a trivial one-liner in Python:

python -c 'import socket; print(socket.gethostbyname(socket.gethostname()))'
John Zwinck
  • 239,568
  • 38
  • 324
  • 436
  • It works on my laptop connected to a cheap home internet connection. `gethostname()` for me returns `myclevername.local` which as you can see is not real DNS, and I didn't set anything up apart from connecting to wi-fi. – John Zwinck May 29 '14 at 13:55
  • Your router/etc. might very well be doing dynamic DNS of a sort for devices that get DHCP leases from it. Try doing a `host` or `dig` on that address and see what you get (and from whom). – Etan Reisner May 29 '14 at 14:07
  • I get NXDOMAIN (not found). Yet the Python code works fine. I agree that there may be "specially configured" hosts on which that Python code will fail, but I don't think they're common. – John Zwinck May 29 '14 at 14:09
  • Do you have a non-localhost entry for that domain in your `/etc/hosts` file? – Etan Reisner May 29 '14 at 14:13
  • Then I don't understand where that response is coming from but ok. That command definitely does not work on at least one system here (but does on at least two others, using `/etc/hosts` information). – Etan Reisner May 29 '14 at 14:23
  • 1
    Worked for me, but this solution is a Pythonic one whilst i'm hoping to get a Bash'ish answer. – Fernando Retimo May 29 '14 at 15:21
2

If you're looking for just "inet" and not "inet6", this works for me:

/usr/bin/ifconfig eth0 | grep --word-regexp inet | awk '{print $2}'

"--word-regexp" will make grep look for the whole word "inet" and not match partials of words, i.e. "inet" won't match "inet6" - "inet" will only match lines with "inet" in them.

Jonathan Le
  • 141
  • 1
  • 2
2

You can also try this

user@linux:~$ cat script.sh
ifconfig | grep ad.*Bc | cut -d: -f2 | awk '{ print $1}'
user@linux:~$ 

Output

user@linux:~$ ./script.sh
192.168.1.1
10.0.1.1
user@linux:~$

Please take note that ifconfig output might be different depending on your linux version. Hence, you might want to change the script accordingly.

Btw, this is my ifconfig output

user@linux:~$ ifconfig 
eth0      Link encap:Ethernet  HWaddr 00:00:00:00:00:10  
          inet addr:192.168.1.1  Bcast:192.168.56.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:112 errors:0 dropped:0 overruns:0 frame:0
          TX packets:93 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:14616 (14.2 KiB)  TX bytes:17776 (17.3 KiB)

eth1      Link encap:Ethernet  HWaddr 00:00:00:00:00:11
          inet addr:10.0.1.1  Bcast:10.0.1.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

user@linux:~$
Charlotte Russell
  • 1,355
  • 1
  • 13
  • 16
0

Similar to JSR, but with awk and cut in reverse order:

my_ip=$(ifconfig en1 | grep 'inet addr' | awk '{print $2}' | cut -d: -f 2)
echo ${my_ip}
Arun
  • 19,750
  • 10
  • 51
  • 60
0

This works for me:
ifconfig eth0 | awk '/inet addr/{print substr($2,6)}'

user3396065
  • 549
  • 5
  • 15
0

Code working on VDS/VPS too:

ifconfig | grep -A2 "venet0:0\|eth0" | grep 'inet addr:' | sed -r 's/.*inet addr:([^ ]+).*/\1/' | head -1

or

ifconfig | grep 'inet addr:' | grep -v 127.0.0.1 | head -n1 | cut -f2 -d: | cut -f1 -d ' '
Geograph
  • 2,274
  • 23
  • 23
0

Taking patch's answer, making it a bit more general,

i.e.: skipping everything till the first digit.

ifconfig eth0 | awk '/inet addr/{sub(/[^0-9]*/,""); print $1}'

Or even better:

ifconfig eth0 | awk '/inet /{sub(/[^0-9]*/,""); print $1}'

  • Please note the print part at the end - changes from $2 to $1.

Using Perl Regex:

ifconfig eth0 | grep -oP '(?<= inet addr:)[^ ]+'

Explanation: grep -oP searches for an EXACT match using Perl regex.
The "tricky" part is the regex itself;
1. (?<= inet addr:) means - that the string inet addr: is to the LEFT of what we're looking for.
2. [^ ]+ (please notice the space after the ^ ) - it means to look for everything until the first blank - in our case it is the IP Address.

AK75
  • 1
  • 3
0

Use:

ifconfig enops3 | grep broadcast | cut -d " " -f10

Where enops3 is the interface name.

Khalid Abdlqader
  • 311
  • 4
  • 11
0

This code outputs IP addresses for all network connections (except loopback) and is portable between most OS X and Linux versions.

It's particularly useful for scripts that run on machines where:

  • The active network adapter is unknown,
  • notebooks that switch between Wi-Fi and Ethernet connections, and
  • machines with multiple network connections.

The script is:

/sbin/ifconfig -a | awk '/(cast)/ {print $2}' | cut -d: -f2

This can be assigned to a variable in a script like this:

myip=$(/sbin/ifconfig -a | awk '/(cast)/ {print $2}' | cut -d: -f2)

Scripts can handle possible multiple addresses by using a loop to process the results, as so:

if [[ -n $myip ]]; then
  count=0
  for i in $myip; do
    myips[count]=$i       # Or process as desired
    ((++count))
  done
  numIPaddresses=$count   # Optional parameter, if wanted
fi

Notes:

  • It filters 'ifconfig' on "cast", as this has an added effect of filtering out loopback addresses while also working on most OS X and Linux versions.
  • The final 'cut' function is necessary for proper function on Linux, but not OS X. However, it doesn't effect the OS X results - so it's left in for portability.
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
azrobbo
  • 61
  • 1
  • 4
0

After trying some solutions i find this most handy, add this to your alias:

alias iconfig='ifconfig | awk '\''{if ( $1 >= "en" && $2 >= "flags" && $3 == "mtu") {print $1}; if ( $1 == "inet" || $1 == "status:"){print $0};}'\''|egrep "en|lo|inet"'

the output looks like this:

shady@Shadys-MacBook-Pro:xxxx/xxx ‹dev*›$ iconfig lo0: inet 127.0.0.1 netmask 0xff000000 en0: inet 10.16.27.115 netmask 0xffffff00 broadcast 10.16.27.255 en1: en2: en5: inet 192.168.2.196 netmask 0xffffff00 broadcast 192.168.2.255

Shadycorp
  • 94
  • 1
  • 4
0

After troubles with greping ifconfig I found a wrapper library to simplify my life

pip install my_ip 
mip
Hritu
  • 1
-1
ifconfig eth0 | awk '/inet addr/{sub("addr:",""); print $2}'
JAL
  • 41,701
  • 23
  • 172
  • 300
patch
  • 9
  • 2
  • While this code may answer the question, providing additional context regarding why and/or how this code answers the question improves its long-term value. – JAL Oct 23 '15 at 22:38
-1

A simple AWK + Bash script example which may give general idea how to parse command output and mix syntaxes together.

Full code is at: https://gist.github.com/darkphase/67d7ec22d47dbebd329e

BEGIN { RS = "" ; FS = "\n" }  # Change separator characters
{
    while ( "'"$cmd"'" | getline ){
        # print $0
        if ( $1 !~ /LOOPBACK/ ){

            split($1,arr," ")
            print "'"$blue"'"arr[1]"'"$reset"'"

            for(i = 1; i <= NF; i++) { # Loop through fields (this case lines)
                split($i,arr," ")
                switch ( arr[1] ) {
                    case "inet":
                        print "'"$red"'" "IPV4:" "'"$reset"'" "\n IP: " "'"$yellow"'" arr[2] "'"$reset"'" "\n NM: "arr[4]"\n BC: "arr[6]
                        break
                    case "inet6":
                        print "'"$red"'" "IPV6:" "'"$reset"'" "\n IP: "arr[2]"\n PL: "arr[4]
                        break
                    case "ether":
                        print "'"$red"'" "MAC: " "'"$reset"'" arr[2]
                        break
                    default:
                }
            }
            print ""
        }
    }
}'
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
darkphas
  • 1
  • 2
  • oh God, haven't you seen the other one liner answers ? – sidney Jan 25 '16 at 01:11
  • Nice script but yours just displays them all, literally no different than using ifconfig .. not useful for the application in a script ... – Mike Q Dec 05 '18 at 15:38