Linux bash script to extract IP address

ip -4 addr show eth0 | grep -oP "(?<=inet ).*(?=/)"

To just get your IP address:

echo `ifconfig eth0 2>/dev/null|awk '/inet addr:/ {print $2}'|sed 's/addr://'`

This will give you the IP address of eth0.

Edit: Due to name changes of interfaces in recent versions of Ubuntu, this doesn't work anymore. Instead, you could just use this:

hostname --all-ip-addresses or hostname -I, which does the same thing (gives you ALL IP addresses of the host).


If the goal is to find the IP address connected in direction of internet, then this should be a good solution.

Edit 2021: Added "sed" and "grep" versions and new "awk" versions (some are gnu)


To find what IP adders is used connected to internet, we can use the ip route command. With newer version of Linux you get more information with a typical output some like this:

ip route get 8.8.8.8
8.8.8.8 via 10.36.15.1 dev ens160 src 10.36.15.150 uid 1002
    cache

so to get IP you need to find the IP after src, using awk, sed or grep

ip route get 8.8.8.8 | awk -F"src " 'NR==1{split($2,a," ");print a[1]}'
ip route get 8.8.8.8 | awk 'match($0,/src (\S*)/,a)&&$0=a[1]'
ip route get 8.8.8.8 | awk '{for(i=1;i<=NF;i++)if($i~/src/)$0=$(i+1)}NR==1'

ip route get 8.8.8.8 | sed -E 's/.*src (\S+) .*/\1/;t;d'
ip route get 8.8.8.8 | sed 's/.*src \([^ ]*\).*/\1/;t;d'
ip route get 8.8.8.8 | sed  -nE '1{s/.*?src (\S+) .*/\1/;p}'

ip route get 8.8.8.8 | grep -oP 'src \K[^ ]+'
10.36.15.150

and if you like the interface name using awk, sed or grep

ip route get 8.8.8.8 | awk -F"dev " 'NR==1{split($2,a," ");print a[1]}'
ip route get 8.8.8.8 | awk 'match($0,/dev (\S*)/,a)&&$0=a[1]'
ip route get 8.8.8.8 | awk '{for(i=1;i<=NF;i++)if($i~/dev/)$0=$(i+1)}NR==1'

ip route get 8.8.8.8 | sed -E 's/.*?dev (\S+) .*/\1/;t;d'
ip route get 8.8.8.8 | sed 's/.*dev \([^ ]*\).*/\1/;t;d'
ip route get 8.8.8.8 | sed  -nE '1{s/.*?dev (\S+) .*/\1/;p}'

ip route get 8.8.8.8 | grep -oP 'dev \K[^ ]+'
ens192

ip route does not open any connection out, it just shows the route needed to get to 8.8.8.8. 8.8.8.8 is Google's DNS.

If you like to store this into a variable, do:

my_ip=$(ip route get 8.8.8.8 | awk -F"src " 'NR==1{split($2,a," ");print a[1]}')

my_interface=$(ip route get 8.8.8.8 | awk -F"dev " 'NR==1{split($2,a," ");print a[1]}')

Why other solution may fail:

ifconfig eth0

  • If the interface you have has another name (eno1, wifi, venet0 etc)
  • If you have more than one interface
  • IP connecting direction is not the first in a list of more than one IF

Hostname -I

  • May get only the 127.0.1.1
  • Does not work on all systems.
  • Give all IP not only the one connected to internet. -I, --all-ip-addresses all addresses for the host

If you want to get a space separated list of your IPs, you can use the hostname command with the --all-ip-addresses (short -I) flag

hostname -I

as described here: Putting IP Address into bash variable. Is there a better way?

Tags:

Linux

Bash

Awk

Sed