Bash script to retrieve name of Ethernet Network interface

In Ubuntu 16.04 I made a script to dinamically configure IP address of the wired ethernet interface based on certain parameters. Now the problem is that in my script I assume that the name is eth0, but this is not always true.. assuming that I have only one wired network interface (not necessary plugged) but I can have also a wireless interface, how can I retrieve its name (just the wired one)?

with ifconfig command I get:

enp7s0    Link encap:Ethernet  HWaddr fc:3f:db:a2:6d:46  
          inet addr:192.168.0.101  Bcast:192.168.0.255  Mask:255.255.255.0
          inet6 addr: fe80::149f:3103:af2f:1ec5/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:6784 errors:0 dropped:0 overruns:0 frame:0
          TX packets:7493 errors:1 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:4565079 (4.5 MB)  TX bytes:827825 (827.8 KB)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:8037 errors:0 dropped:0 overruns:0 frame:0
          TX packets:8037 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1 
          RX bytes:2261250 (2.2 MB)  TX bytes:2261250 (2.2 MB)

wlp19s0   Link encap:Ethernet  HWaddr c8:ff:28:93:26:32  
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:180463 errors:0 dropped:0 overruns:0 frame:0
          TX packets:121275 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:229823414 (229.8 MB)  TX bytes:15675806 (15.6 MB)

What I want is:

enp7s0

Solution 1:

If you want to exclude interfaces like vir , loopback and wl(wireless) then the following should do the trick.

ip link | awk -F: '$0 !~ "lo|vir|wl|^[^0-9]"{print $2;getline}'

Here we use colon as delimiter -F: then check if the row $0 does not match a certain string using regular expression.

Solution 2:

Because all interfaces would displayed under /sys/class/, such as /sys/class/net/ listing all network interfaces,

it is possible to directly use this directly search and return the exact interface name through a simple keyword like:

ls /sys/class/net | grep enp

Solution 3:

I'd use ifconfig(bit old and deprecated) tool or ip command. Using ip route you are having a list of available routes. Then get only line containing default with grep and strip the unwanted characters off the string using sed

full command goes like:

ip route | grep default | sed -e "s/^.*dev.//" -e "s/.proto.*//"

Solution 4:

Here is best solution

ip route get 8.8.8.8 | awk -- '{printf $5}'

or

echo $(ip route get 8.8.8.8 | awk -- '{printf $5}')

in bash script you can declare main_interface and use anywhere as $main_interface

main_interface=$(ip route get 8.8.8.8 | awk -- '{printf $5}')

Solution 5:

Assuming you got only one physical interface and not some wlan interface etc. The trick is to get the interfaces. Which are in /sys/class/net and then look where they go to.

find /sys/class/net ! -type d | xargs --max-args=1 realpath  | awk -F\/ '/pci/{print $NF}'

If you got more interfaces you would have to grep lspci first:

lspci  | awk '/Ethernet/{print $1}'

The whole thing would turn into:

pci=`lspci  | awk '/Ethernet/{print $1}'`; find /sys/class/net ! -type d | xargs --max-args=1 realpath  | awk -v pciid=$pci -F\/ '{if($0 ~ pciid){print $NF}}'