10

I need to create a script that outputs the internal IP address, that is configured as the default Interface.

terdon
  • 242,166

10 Answers10

12

Lots of good answers here, but wanted to throw in my usual approach:

The simplest solution is to get the route for a public internet address:

$ ip route get 1.1.1.1 | grep -oP 'src \K\S+'
192.168.0.20

Another solution is to get the default gateway, and then get the IP addr used to communicate with that gateway:

$ ip route get $(ip route show 0.0.0.0/0 | grep -oP 'via \K\S+') | grep -oP 'src \K\S+'
192.168.0.20
phemmer
  • 71,831
7

Here's another slightly terser method using procfs (assumes you're using Linux):

default_iface=$(awk '$2 == 00000000 { print $1 }' /proc/net/route)
ip addr show dev "$default_iface" | awk '$1 ~ /^inet/ { sub("/.*", "", $2); print $2 }'

This returns both the IPv4 and (if available) the IPv6 address of the interface. You can change the test if you only want one or the other (look for inet for IPv4, and inet6 for IPv6).


$ default_iface=$(awk '$2 == 00000000 { print $1 }' /proc/net/route)
$ ip addr show dev "$default_iface" | awk '$1 ~ /^inet/ { sub("/.*", "", $2); print $2 }'
10.0.2.15
fe80::a00:27ff:fe45:b085
$ ip addr show dev "$default_iface" | awk '$1 == "inet" { sub("/.*", "", $2); print $2 }'
10.0.2.15
$ ip addr show dev "$default_iface" | awk '$1 == "inet6" { sub("/.*", "", $2); print $2 }'
fe80::a00:27ff:fe45:b085
Chris Down
  • 125,559
  • 25
  • 270
  • 266
1

Here's what I wrote:

  1. Get the default interface from the "route" command.

It will print out which interface is the "default". For my host, I need to get the last column of the default line.

[root@pppdc9prd3ga mdesales]# route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
192.168.4.0     *               255.255.252.0   U     0      0        0 bridge0
10.132.60.0     *               255.255.252.0   U     0      0        0 eth4
link-local      *               255.255.0.0     U     1002   0        0 eth4
link-local      *               255.255.0.0     U     1003   0        0 bridge0
default         10.132.60.1     0.0.0.0         UG    0      0        0 eth4
  1. Use "ifconfig" to retrieve the IP address of that interface.

Just getting the addr: value.

[root@pppdc9prd3ga mdesales]# ifconfig eth4
eth4      Link encap:Ethernet  HWaddr 00:50:56:01:42:91  
          inet addr:10.132.63.191  Bcast:10.132.63.255  Mask:255.255.252.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:1346288 errors:0 dropped:0 overruns:0 frame:0
          TX packets:438844 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:276243478 (263.4 MiB)  TX bytes:116188062 (110.8 MiB)

So here's the script I came up with.

/app/myPublicIp.sh 
defaultInterface=$(route | grep default | awk '{print $(NF)}')
ifconfig $defaultInterface | grep 'inet addr:' | cut -d: -f2 |  awk '{ print $1}'

Here's it executing:

/app/ipFor.sh 
10.132.63.191
Rui F Ribeiro
  • 56,709
  • 26
  • 150
  • 232
1

My favorite one is following.

Get the default interface:

$ ip r | grep -oP 'default .* \K.+'
eth0

Get the ip of an interface:

$ ip a show eth0 | grep -oP 'inet \K[\d\.]+'
10.33.44.135

Combined:

$ ip a show $(ip r | grep -oP 'default .* \K.+') | grep -oP 'inet \K[\d\.]+'
10.33.44.135
Ashald
  • 11
  • Unfortunately these fail on RHEL/CentOS 8 as the ip r output has changed slightly, with the metric being the last entry on the line and not the dev ensNNN or dev ethN. – dragon788 May 16 '22 at 16:40
1

One other approach is:

ip a|awk /$(ip r|awk '/default/ { print $5 }')/|awk '/inet/ { print $2 }'| cut -f1 -d"/"

the benefit of this is that uses only ip a and ip r that is available by default at all linux systems

0

If what you want is the IP address assigned to the default interface (which is what I understood from the comments under the question), using the Swiss army knife of network setup (ip) should be enough:

$ ip route | grep '^default'
default via 10.176.143.1 dev eth1  metric 203 
$ ip addr show eth1
4: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether c0:de:f1:72:30:48 brd ff:ff:ff:ff:ff:ff
    inet 10.176.143.71/24 brd 10.176.143.255 scope global eth1
       valid_lft forever preferred_lft forever

This shortens to

$ ip addr show \
    $( /sbin/ip route \
        | grep '^default'\
        | sed 's/^.*dev \([^ \t]*\) .*$/\1/' )

which is ugly, because it is parsing something that probably wasn't really meant to be parsed (output of ip route), but should work.

peterph
  • 30,838
0

Simple Command with the default interface.

ip -o route get "8.8.8.8" 2>/dev/null | sed -e 's/^.* src \([^ ]*\) .*$/\1/'  

or

ip route | grep src | awk -F 'src' '{print $NF; exit}' | awk '{print $1}'

or

ip route | sed -n 's/.* src \(.*\) metric .*/\1/p' | uniq

Tested on All Unix OS

M.S.Arun
  • 291
  • Unfortunately this fails on RHEL/CentOS 8 as the ip r output has changed slightly, with the metric being the last entry on the line and not the dev ensNNN or dev ethN so it prints the whole line instead of just the IP. – dragon788 May 16 '22 at 16:43
  • @dragon788 - Please read my updated answer. Hope this should work!! – M.S.Arun May 17 '22 at 05:17
0

This worked for me on Centos 7. Find default interface using ip

ifconfig $(ip route | awk '/default/ { print $5 }') | grep "inet " | awk '{print $2}'
N A
  • 101
0

Any Linux OS-es using /proc (but without using iproute tools):

cat /proc/net/fib_trie|grep -A50 '\|-- 0\.0\.0\.0$'|grep -B50 -wm1 'LOCAL'|tail -n2|grep -oP '\|-- \K\S+'
TPS
  • 2,481
0

To return the IP address of the default interface from a script, you can use the following commands:

IP=$(hostname -I)
echo $IP

or simply:

hostname -I

This works on Ubuntu and Raspberry Pi OS, but not on macOS.

nico
  • 101
  • Please note that this will display all IP addresses on all interfaces, not just the one with the default route to the internet. – AdminBee Jun 06 '23 at 14:32