16
votes

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?

20
Which OS? Which ifconfig?Tripp Kinetics
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
/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 rootuser3442743

20 Answers

25
votes

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

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

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

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.

7
votes

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
5
votes

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.

3
votes

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

2
votes

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

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.

2
votes

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

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}
0
votes

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

0
votes

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

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.

0
votes

Use:

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

Where enops3 is the interface name.

0
votes

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

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

0
votes

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

pip install my_ip 
mip
-1
votes
ifconfig eth0 | awk '/inet addr/{sub("addr:",""); print $2}'
-1
votes

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