Build a network speed monitor in bash with AWK

navarroaxel

Axel Navarro

Posted on January 6, 2021

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.

💖 💪 🙅 🚩
navarroaxel
Axel Navarro

Posted on January 6, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related