Parse ifconfig to get only my IP address using Bash

夙愿已清 提交于 2019-11-27 07:41:01
Etan Reisner

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}'

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

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.
JSR

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}'  
Fernando Retimo

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.

slm

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

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

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.

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()))'

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:~$

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.

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}

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

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

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.

Khalid Abdlqader

Use:

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

Where enops3 is the interface name.

azrobbo

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.

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

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

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 ""
        }
    }
}'
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!