DEV Community

Cover image for Build a network speed monitor in bash with AWK
Axel Navarro for Cloud(x);

Posted on

Build a network speed monitor in bash with AWK

Sometimes we need to measure the network speed of a server, but services like speedtest are not useful because we want to check our bandwidth against another cloud service and not the internet itself.

AWK to the rescue

We can write a simple script in AWK to parse the /proc/net/dev pseudo-file which contains network device status information. AWK is a programming language to manipulate columns of data that we can't solve with a simple sed command and a regex.

But before talking about the AWK script, we should define the sentences in bash that we need in this script. Or, you can jump to the end to find the complete script 😁.

The bash side

We need to create a .sh file with an infinite loop to print the network speed every 2 seconds.

INTERFACE=eth0
echo "$INTERFACE  down (KiB/s)   up (KiB/s)"
while :
do
  # The AWK command here!
  sleep 2;
done
Enter fullscreen mode Exit fullscreen mode

First, we declare the variable INTERFACE with the name of the network interface to be inspected - in this example is eth0.

Then, we print a nice header to remind ourselves which column is the download speed (and the upload one). These speeds are measured in kilobytes per second (KiB/s, the i is because 1 Kibibyte is 1024 bytes).

Finally, we start the infinite loop with a sleep of 2 seconds between iterations. Don't worry, this script can be stopped using Ctrl+C.

Comparing the dev pseudo-file in time

We want to measure the network speed in KiB per second, so we should read the /proc/net/dev file and compare it against a new read from the same file after 1 second. For this, we can use a little bash trick called process substitution.

awk '...' \
  <(grep $INTERFACE /proc/net/dev) \
  <(sleep 1; grep $INTERFACE /proc/net/dev)
Enter fullscreen mode Exit fullscreen mode

We use grep to read the line of our interface, and after waiting for 1 second we must read the line of our interface again.

Mr. Bean magic

The AWK script

If we check the output of /proc/net/dev

cat /proc/net/dev
Enter fullscreen mode Exit fullscreen mode

We'll see that the 1st column is the interface name, the 2nd column is the received bytes (rx) and the 10th column is the transmitted bytes (tx).

We should save the first read in the rx and tx variables, and then print the difference between the 2nd read and the first one. But, we could divide the result by 1024 because KiB/s is a better human readable format than B/s.

{
  if (rx) {
    print "  "($2-rx)/1024"    "($10-tx)/1024
  } else {
    rx=$2; tx=$10;
  }
}
Enter fullscreen mode Exit fullscreen mode

We can see its output by running:

$ ./net-monitor.sh
eth0  down (KiB/s)   up (KiB/s)
  0.123047    0.0683594
  5.38086    6.18457
  1132.12    70.1748
Enter fullscreen mode Exit fullscreen mode

If we want to round the decimal part we can use the printf function.

{
  if (rx) {
    printf("  %.0f    %.0f\n", ($2-rx)/1024, ($10-tx)/1024)
  } else {
    rx=$2; tx=$10;
  }
}
Enter fullscreen mode Exit fullscreen mode

The bash script

This is our final bash script

echo "$INTERFACE  down (KiB/s)   up (KiB/s)"
while :
do
  awk '{
  if (rx) {
    printf ("  %.0f    %.0f\n", ($2-rx)/1024, ($10-tx)/1024)
  } else {
    rx=$2; tx=$10;
  }
}' \
    <(grep $INTERFACE /proc/net/dev) \
    <(sleep 1; grep $INTERFACE /proc/net/dev)
  sleep 2;
done
Enter fullscreen mode Exit fullscreen mode

And it's ready! Just open a terminal and run the script to monitor the network speed while you're running your network process.

Top comments (5)

Collapse
 
alltorx profile image
Buffalo_Overflow • Edited

Thanks! Worth noting that if your default shell is not bash, this may not work, but adding in #!/bin/bash to the top will instruct bash to execute the rest of the script.

I note this because I was scratching my head for a minute or two trying to figure out why it wasn't working - ha.

Collapse
 
navarroaxel profile image
Axel Navarro

Oh sorry for that! 🙏 I tried to keep the code easy and clean lol.

Collapse
 
alltorx profile image
Buffalo_Overflow

Oh nothing to be sorry about at all, it was just in case someone else had the same issue. Most folks will be using bash, and if they're not, will probably be aware of what to do! (:

Collapse
 
rsvp profile image
Аqua 🜉іtæ ℠

In such a manner, but in pair with aosd_cat (man: displays text on the screen) I get my local temp (t°) warning (⚠) right on screen when heat is too high. It appears ss a prompt notice to handle particular process just in time. But conky (man: system monitor for X originally based on the torsmo code) very long time do for me what you want to achieve.

Collapse
 
pabloromeo profile image
Pablo Romeo

Excelent post!! Thanks!
Also, if you ever need to test the max transfer speed between machines on your network you can use iperf/iperf3. It's cross-platform and very easy to use :)