4

I want to count the number of entries starting with the string "tun" that I get as output of the command ifconfig.

For example, if this is my output, I want to count to be 2. I tried to play around with grep, but it is still not solved.

docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.0.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:16:73:86:ba  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

enp0s31f6: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        ether 00:00:00:00:00:00  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        device interrupt 16  memory 0xa1300000-a1320000

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 905  bytes 80293 (80.2 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 905  bytes 80293 (80.2 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

tun0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST>  mtu 1500
        inet 00.00.00.00  netmask 255.255.255.255  destination 192.168.105.77
        inet6 ::  prefixlen 64  scopeid 0x20<link>
        unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 100  (UNSPEC)
        RX packets 438  bytes 52174 (52.1 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 457  bytes 33911 (33.9 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

tun1: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST>  mtu 1500
        inet 0.0.0.0  netmask 255.255.255.255  destination 192.168.104.61
        inet6 ::  prefixlen 64  scopeid 0x20<link>
        unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 100  (UNSPEC)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 10  bytes 584 (584.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
1
  • 2
    This is a work order, not a question. Aren't any research or (demonstrated) own attempts required? Nov 7 '19 at 16:23
12

It is possible using either a combination of grep and wc, or using awk

First approach, using grep:

ifconfig | grep "^tun" | wc -l

This will pipe the output of ifconfig through grep, match all lines starting with the string tun (this is accomplished using the "anchor" indicator ^), and then use wc to count the lines which grep output as matched.

As pointed out by @schaiba, it is even possible without resorting to wc by virtue of grep's -c option, which will count all matched lines by itself:

ifconfig | grep -c "^tun"

Second approach, using awk:

ifconfig | awk 'BEGIN {tuns=0}; /^tun/ {tuns++}; END {print tuns}'

This will pipe the output to awk. The awk program, enclosed between single quotes ' ... ', does the following:

  • at the beginning (BEGIN { ... }), initialize an internal varible tuns, which we will use for book-keeping, as 0
  • in the main loop, for every line encountered that starts with the string tun (indicated by the regular expression /^tun/), increase the counter tuns
  • after the input is finished, (END { ... }), output the resulting value of tuns
5
  • 7
    grep has a -c (count) flag that does what the OP wants without the extra need for wc.
    – schaiba
    Nov 6 '19 at 10:34
  • 1
    Good point. Do you want to post your own answer, or shall I edit mine?
    – AdminBee
    Nov 6 '19 at 10:36
  • Edit yours, I left it as a comment just to complete what you said. Good answer, btw.
    – schaiba
    Nov 6 '19 at 10:40
  • This is a very good and informative answer. Thank you @AdminBee! If you are still not getting the correct answer, there is the possibility of white space in front of the tun. (There shouldn't be, but I've see lots of weird stuff). To adjust for that, in the grep command you can add [.space. .tab.].asterisk. between the ^ and the tun. Or, some versions of Linux allow [[:blank:]].* instead.
    – Scottie H
    Nov 6 '19 at 18:46
  • Be careful ! This method does what you ask, but it could be that this is not what you actually mean: ifconfig only shows configured interfaces. You might be interested in all interfaces in which case you need ifconfig -a
    – Garo
    Nov 6 '19 at 20:40
12

You probably don't need ifconfig (or ip) for this. The interfaces are listed in /sys/class/net:

% ls /sys/class/net
eth0  lo  tun0  tun1  tun2  wlan0

So, you can count the directories there, with something like:

$ printf "%s\n" /sys/class/net/tun* | wc -l
3
5
  • 6
    Or better (shopt -s nullglob; set -- /sys/class/net/tun*; echo "$#") or with zsh: (){echo $#} /sys/class/net/tun*(N) Nov 6 '19 at 10:46
  • Yet another method using sysfs: for device in /sys/class/net/tun* ; do echo $device ; done | wc -l. (But in "real life" I would also use ifconfig, see AdminBee's answer)
    – Garo
    Nov 6 '19 at 20:34
  • 1
    (In real life, I've often had to deal with docker images, at least some of which don't have ifconfig or ip installed.)
    – muru
    Nov 7 '19 at 0:51
  • Note that your naive version prints 1 instead of 0 when there are no tun interfaces. Nov 7 '19 at 8:05
  • Yes, the method of counting here isn't perfect. However, what I wanted to show here is that instead of parsing ifconfig or ip output, the problem can be reduced to counting entries in a directory, which is a far more common problem, with plenty of methods in many languages.
    – muru
    Nov 7 '19 at 8:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.