Parse ifconfig to get only my IP address using Bash
Asked Answered
G

20

20

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?

Gavriella answered 29/5, 2014 at 13:23 Comment(3)
Which OS? Which ifconfig?Stacked
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.Tanhya
/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 rootTabbitha
G
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.

Gavriella answered 29/5, 2014 at 15:24 Comment(2)
this will do it for you too: ifconfig en1|awk '/inet / {print $2}'Blown
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"Ohg
P
28

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}'
Pippy answered 29/5, 2014 at 13:46 Comment(5)
I don't want to question you answer but I'm using Mac OSX. Thanks though.Gavriella
@FernandoRetimo What is the raw output from ifconfig and ip on OS X?Pippy
ifconfig one didn't work for me on CentOS 7. But ip addrone worked for me. Thanks.Furnishings
@TyagiAkhilesh ifconfig is deprecated (and has been for ages) and CentOS 7 doesn't ship with it by default anymore.Pippy
Running a command to parse its output without forcing the locale is like shooting a bullet in your foot. Use LC_ALL=C ifconfig instead of just ifconfig.Sahara
D
25

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.
Dactylic answered 13/5, 2016 at 14:29 Comment(2)
That answer Hit the spot for meStanwood
ifconfig doesn't come with some distros like proxmox. If one address is fine, just go for hostname -I 2>/dev/null || ipconfig getifaddr en0Graces
H
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}'  
Henbit answered 29/5, 2014 at 13:49 Comment(3)
Since I am awk-phobic, I have a slightly different version: ifconfig eth0 | grep "inet\ addr" | cut -d: -f2 | cut -d" " -f1Egger
Does not work on Mac OSX ... The reason is that the syntax of the ifconfig is a bit different. Thanks though.Gavriella
There is a similar post on so. Hope this helps! #7182498Henbit
G
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.

Gavriella answered 29/5, 2014 at 15:24 Comment(2)
this will do it for you too: ifconfig en1|awk '/inet / {print $2}'Blown
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"Ohg
F
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
Frantz answered 6/9, 2014 at 13:6 Comment(0)
O
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.

Ohg answered 17/2, 2016 at 16:42 Comment(0)
O
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

Odaodab answered 18/12, 2015 at 16:46 Comment(0)
S
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()))'
Sayce answered 29/5, 2014 at 13:36 Comment(6)
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.Sayce
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).Pippy
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.Sayce
Do you have a non-localhost entry for that domain in your /etc/hosts file?Pippy
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).Pippy
Worked for me, but this solution is a Pythonic one whilst i'm hoping to get a Bash'ish answer.Gavriella
P
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.

Probably answered 23/2, 2015 at 21:26 Comment(0)
C
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:~$
Content answered 14/6, 2017 at 13:52 Comment(0)
G
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}
Galactose answered 8/8, 2015 at 0:41 Comment(0)
K
0

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

Karat answered 1/9, 2015 at 14:21 Comment(0)
N
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 ' '
Nuptials answered 18/10, 2015 at 6:10 Comment(0)
P
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.

Phaedra answered 3/11, 2015 at 8:15 Comment(0)
E
0

Use:

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

Where enops3 is the interface name.

Estivate answered 7/11, 2015 at 10:51 Comment(1)
Note should be grep not greb (would edit answerbut says the queue is full).Botchy
C
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.
Clarendon answered 3/1, 2016 at 0:14 Comment(0)
I
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

Ice answered 29/3, 2016 at 8:49 Comment(0)
G
0

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

pip install my_ip 
mip
Girlish answered 29/6, 2020 at 11:42 Comment(1)
ifconfig is not used now days. Instead, we have ipWaddington
E
-1
ifconfig eth0 | awk '/inet addr/{sub("addr:",""); print $2}'
Esqueda answered 23/10, 2015 at 22:7 Comment(1)
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.Oneill
M
-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 ""
        }
    }
}'
Mallon answered 23/1, 2016 at 0:11 Comment(2)
oh God, haven't you seen the other one liner answers ?Ingra
Nice script but yours just displays them all, literally no different than using ifconfig .. not useful for the application in a script ...Ohg

© 2022 - 2024 — McMap. All rights reserved.