108

I have eth0 and wlan0 according to ifconfig and I can ping google.com.

How can I find out (with a normal user, not root) what interface is active, as in, what interface did the ping (or whatever, ping is not mandatory) use?

I am using Ubuntu 11.04 or Fedora 14

2
  • 4
    The below solutions seem to want you to do the inferring yourself, which doesn't seem right. (And everybody's routing tables look incredibly straightforward!) While I'm looking for the Windows equivalent, it appears that "ip route get <ip-address>" will tell you which interface would be used if you were to attempt to connect to a given ip address.
    – mwardm
    Aug 25, 2016 at 9:41
  • Related on Server Fault: Find interface for route to specific host (which is what I was looking for when I wound up here).
    – Wildcard
    Jul 12, 2019 at 22:19

12 Answers 12

81

You can use route to find your default route:

$ route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
192.168.1.0     *               255.255.255.0   U     1      0        0 eth0
link-local      *               255.255.0.0     U     1000   0        0 eth0
default         192.168.1.1     0.0.0.0         UG    0      0        0 eth0

The Iface column in the line with destination default tells you which interface is used.

12
  • 1
    @Job in case we have an IP address how can we find which interface it uses.
    – Bionix1441
    Nov 30, 2017 at 9:51
  • 4
    This should not be the accepted answer. If iproute have been used to define custom routing rules route can't be used. @Torgeir have the wright answer. Feb 20, 2019 at 18:40
  • 2
    This answer is not correct. For example (and given the same routes displayed in the answer), if you ping 192.168.1.16 (a pc on your local network), the entry which starts with 192.168.1.0... is the route that will be used. Of course in this case it refers to the same Iface, but that is just because you have one interface on your machine.
    – kdehairy
    Apr 25, 2019 at 19:27
  • 1
    @Job Even with google.com, if you have two routes each on a different interface, the match with the longer mask will be picked (not necessarily the default). All what default means, is that if no other route is found, let's consult this one :)
    – kdehairy
    Apr 27, 2019 at 11:51
  • 5
    I get a line "default ... eth0" and a line "default ... wlan0". So which one is the real default?
    – AstroFloyd
    Jul 10, 2019 at 7:44
50

My version which is basically based on this and this:

route | grep '^default' | grep -o '[^ ]*$'

And this, experimentally, for macOS:

route -n get default | grep 'interface:' | grep -o '[^ ]*$'
7
  • 1
    is there a way for you to translate this for OSX? Sep 28, 2017 at 21:41
  • 2
    @JohnAllard: let me know if my update now gives correct answer there for macOS. Oct 10, 2017 at 21:11
  • 5
    you don't need multiple pipes, just use route |awk '/^default/{print $NF}'
    – P....
    Apr 30, 2019 at 15:00
  • 2
    I get two lines: "eth0" and "wlan0", so I still don't know which one is active...
    – AstroFloyd
    Jul 10, 2019 at 7:46
  • The mac OS suggestion worked for me, thanks! In my case, "netstat -rn" lists two default interfaces, since the machine has a wired and a wifi interface. It was useful to confirm which one has precedence.
    – Thagomizer
    May 13, 2020 at 2:41
31

On GNU/Linux systems:

#!/bin/sh

# host we want to "reach"
host=google.com

# get the ip of that host (works with dns and /etc/hosts. In case we get  
# multiple IP addresses, we just want one of them
host_ip=$(getent ahosts "$host" | awk '{print $1; exit}')
    
# only list the interface used to reach a specific host/IP. We only want the part
# between dev and the remainder (use grep for that)
ip route get "$host_ip" | grep -Po '(?<=(dev ))(\S+)'
4
  • 3
    Please explain what these commands are doing. Also, you're probably pretty safe here, because you know what your values are, but, generally, you should quote shell variables references (unless you have a good reason not to, and you’re sure you know what you’re doing). Oct 30, 2014 at 18:51
  • 1
    Done, to some extent. Only posted this because I could not find anything that did exactly this. Am using this as a custom fact in a puppet manifest...
    – Torgeir
    Oct 30, 2014 at 20:15
  • Your answer is more correct if the host is an input argument to the script. As the route (and hence the interface) might be different for different ips.
    – kdehairy
    Apr 25, 2019 at 19:52
  • My slight adjustment to the grep part: grep -Po '(?<= dev ).+?(?= (src|proto))'
    – Kevin Li
    May 9, 2020 at 17:28
23

One liner:

ip route get 8.8.8.8 | sed -n 's/.*dev \([^\ ]*\).*/\1/p'

10
  • There's a dangling quote there. Doesn't work at all as-is
    – Krease
    Jan 24, 2018 at 19:23
  • @Krease Author updated his answer Jul 10, 2018 at 16:07
  • @MarinosAn I guess it depends of the system... I needed to modify your snippet to used print $5 instead of print $3...
    – billy
    Jul 15, 2020 at 11:21
  • @billy It would be good to provide your OS to keep here as a reference.
    – Marinos An
    Jul 15, 2020 at 11:31
  • 3
    +1 for the ip route get 8.8.8.8, the rest doesn't work on ubuntu 18.04. I used something simpler: ip route get 8.8.8.8 | head -n1 | awk '{print $5}'
    – Marinos An
    Jul 16, 2020 at 9:02
15

Get the default network interface typically used to route to the "remaining" internet in opposite to DMZ, private network, VM host etc. which are usually routed explicitly.

$ ip route get 8.8.8.8 | sed -n 's/.* dev \([^\ ]*\) .*/\1/p'
eth0
5
  • 2
    it is not always the default route that gets you to where you want. Although the OP most probably is using the default route to get to the internet, this is a generalization and might not always hold true. A word of caution
    – MelBurslan
    Aug 10, 2016 at 17:35
  • Sure, it is only default network interface. If there are multiple connections, one should not really speak about "connecting to the internet", but rather about network interface used for routing to the exact destination.
    – EugeneP
    Aug 22, 2016 at 11:06
  • You do not need to use multiple pipes/greps , ip -4 route ls |awk '/^default/{print $5}'
    – P....
    Apr 30, 2019 at 15:01
  • There could be multiple "defaults" if multiple NICs of a single server/pc are plugged into a switch wired to the gateway Aug 9, 2022 at 2:10
  • @DanglingPointer fixed. thanks for the comment.
    – h0tw1r3
    Aug 10, 2022 at 15:21
11

Different distros of Linux, Unix, some versions of Microsoft Windows, and many other Operating Systems are not limited to using just one network interface to reach the internet.  Many Operating Systems will detect more than one valid interface, capable of reaching the internet, and set up each of them for carrying traffic to the internet (specifically, gateways that ultimately connect to the internet).

If the OS tries to reach an external network and succeeds using eth0, it will add that interface to the routing table and tie it to that network.  If the OS tries to reach the same external network and also succeeds using eth1, it will also add that interface (eth1) into the routing table as an additional way to reach that same network.  Other posters thus far have not considered the importance of the metric values in a routing table.

My routing table, below, shows two different interfaces, eth0 and wlan0.  Both are up, both have been set automatically by the operating system as default routes to the gateway 192.168.1.1, and both have had a route built automatically by the operating system to the 192.168.1.X (i.e., 192.168.1.0/24) network.  This entire routing table was written automatically by the OS.  No edits to it were made by me. The difference shown here is that the wired ethernet interface (eth0) has a lower metric (202), and thus more of my traffic to nodes beyond my own network will be routed through this interface (it is preferred by the lower metric), while the remainder of my traffic to nodes beyond my network will be routed through the wireless interface (wlan0) (it has a higher metric of 303, and thus is less preferred by the OS).

pi@raspberrypi:~ $ route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         192.168.1.1     0.0.0.0         UG    202    0        0 eth0
default         192.168.1.1     0.0.0.0         UG    303    0        0 wlan0
192.168.1.0     0.0.0.0         255.255.255.0   U     202    0        0 eth0
192.168.1.0     0.0.0.0         255.255.255.0   U     303    0        0 wlan0

Both interfaces are being used to reach "the internet", and their use is weighted by the "Metric" values, as can be seen in the bytes and packets statistics for eth0 and wlan0 below:

pi@raspberrypi:~ $ ip -s address
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
    RX: bytes  packets  errors  dropped overrun mcast   
    0          0        0       0       0       0       
    TX: bytes  packets  errors  dropped carrier collsns 
    0          0        0       0       0       0       
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether dc:a6:32:31:a2:c7 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.195/24 brd 192.168.1.255 scope global dynamic noprefixroute eth0
       valid_lft 80787sec preferred_lft 69987sec
    inet6 fe80::2f3f:3f1d:8c35:a05e/64 scope link 
       valid_lft forever preferred_lft forever
    RX: bytes  packets  errors  dropped overrun mcast   
    14341060   22393    0       0       0       971                             ←—— high
    TX: bytes  packets  errors  dropped carrier collsns 
    1190274    10745    0       0       0       0                               ←—— high
3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether dc:a6:32:31:a2:c8 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.193/24 brd 192.168.1.255 scope global dynamic noprefixroute wlan0
       valid_lft 80787sec preferred_lft 69987sec
    inet6 fe80::4f31:5fcf:8f70:b5ca/64 scope link 
       valid_lft forever preferred_lft forever
    RX: bytes  packets  errors  dropped overrun mcast   
    4963408    7954     0       0       0       929                             ←—— lower
    TX: bytes  packets  errors  dropped carrier collsns 
    49371      235      0       0       0       0                               ←—— lower

As the annotations indicate, eth0 is being given more traffic by the OS.

Many Operating Systems will give a lower metric to a wired interface that has a faster connection, and a higher metric to a wired interface with a slower connection.  For example, if eth0 and eth1 both connect to the same node, but eth0 negotiated a 100 Mbs connection, and eth1 negotiated only a 10 Mbs connection, eth0 would be given a lower metric than eth1.  Similarly, many Operating Systems will give a lower metric to a wired interface, and a higher metric to a wireless interface.

More than one interface can be set up automatically (depending on the OS), or manually, to reach the same external node by making/editing entries to the routing table.


A minimally tested script to find the interface with the lowest metric as reported by route: [Added by G-Man]

route | awk '
        BEGIN           { min = -1 }
        $1 == "default" {
                            if (min < 0  ||  $5 < min) {
                                min   = $5
                                iface = $8
                            }
                        }
        END             {
                            if (iface == "") {
                                print "No \"default\" route found!" > "/dev/stderr"
                                exit 1
                            } else {
                                print iface
                                exit 0
                            }
                        }
        '

You might want to extend this to look at the "Flags"; i.e., $4.

1
  • 2
    This would be the best answer here for those with multiple NICs, which I believe should be everyone here if they are asking the OP's question? Aug 9, 2022 at 2:07
5

Running ifconfig will give you the information you need.

The active interface will have an inet addr and will show a record of transmitted data, like so:

RX bytes:1930741 (1.8 Mb)  TX bytes:204768 (199.9 Kb)

You can also use the ip addr command and any inactive interfaces will be designated as having: NO-CARRIER.

7
  • Since OP doesn't want to be root, maybe you should give full path to the executable?
    – tshepang
    Jun 14, 2011 at 7:21
  • Neither command requires elevated privileges.
    – jasonwryan
    Jun 14, 2011 at 7:24
  • 1
    Ubuntu and Arch: both run with normal privileges (although on Ubuntu it is /sbin)
    – jasonwryan
    Jun 14, 2011 at 7:50
  • 1
    @Shadur Not on my install of Ubuntu 10.10 and according to help.ubuntu.com/community/EnvironmentVariables the default $PATH is /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:
    – jasonwryan
    Jun 14, 2011 at 18:32
  • 3
    This won't necessarily help on a system with multiple interfaces, as the poster indicated having. A better answer is using the route command though that wouldn't necessarily be foolproof either due to routing. The default route does not have to be the one to get to the Internet though it may often be. Aug 10, 2016 at 18:36
5

The command ip route ls will give a list of active routes and their sources:

caleburn: ~/ >ip route ls
192.168.10.0/24 dev eth0  proto kernel  scope link  src 192.168.10.7 
default via 192.168.10.254 dev eth0 
3

Use this command:

$ route | grep default | awk '{print $8}'
enp0s3
3
  • [root@linux1 network-scripts]# route|grep default | awk '{print $8}' enp0s3 [root@linux1 network-scripts]#
    – Larry Catt
    Aug 17, 2016 at 16:46
  • 3
    Useless use of grep :) awk ‘/default/{print $8}’
    – Dani_l
    Apr 1, 2022 at 18:41
  • There could be multiple "defaults" if multiple NICs of a single server/pc are plugged into a switch wired to the gateway Aug 9, 2022 at 2:11
1
Debian: apt-get install net-tools
Alpine: apk add net-tools
Arch Linux: pacman -S net-tools
CentOS: yum install net-tools
Fedora: dnf install net-tools
route | head -3 | tail -1 | tr -s " " | cut -d " " -f8

Debian: apt-get install iproute2
Alpine: apk add iproute2
Arch Linux: pacman -S iproute2
CentOS: yum install iproute2
Fedora: dnf install iproute2
OS X: brew install iproute2
ip route | head -1 | cut -d " " -f5
1
  • 1
    Thanks for posting an answer. Please consider adding some text to explain what each block of code / commands means. Although useful, your answer might be hard to understand for unexperienced users
    – Zé Loff
    Apr 7, 2022 at 11:24
0

If your machine has multiple interfaces (which I assume), there is no one interface that will be used for connecting to the internet.

Depending on the destination you are connecting to, your system will consult the ip table (the one shown when you do route command) to find the next hope/router, when it does find one, it will use the interface associated with it.

That said, please refer to @torgeir's answer as it does exactly that:

  1. Given a domain (hardcoded as google.com, which is the only bad point in the answer)
  2. Resolves it's ip
  3. Consults the ip table for the route to use (and hence the interface).
0

Even shorter one liner: ip route show default | cut -d " " -f 5

or

ip route show default | sed -n 's/.* dev \([^\ ]*\) .*/\1/p'

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .