Parse ifconfig to get only my IP address using Bas

2019-01-08 20:58发布

问题:

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?

回答1:

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


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


回答3:

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


回答4:

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.



回答5:

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


回答6:

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



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



回答8:

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


回答9:

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.



回答10:

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


回答11:

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}


回答12:

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



回答13:

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


回答14:

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.



回答15:

Use:

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

Where enops3 is the interface name.



回答16:

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.


回答17:

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



回答18:

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


回答19:

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