How to Write a Bash Script

In our blogs on Linux for Network engineers we’ve been talking mostly about individual commands and how to use them. One of the most powerful capabilities of Linux is the ability to automate tasks by writing programs or scripts.

One of the easiest (and readily available) ways to get started with coding on Linux is with creating a Bash script. Bash is a shell language which is an interpreter of commands between the command line interface and the operating system. If you are using one of the most popular Linux distributions (Ubuntu, Debian, Fedora), then you have most likely used Bash before. You can also find it on MacOs and on Windows 10.

I like teaching by example, so I am not going to list all of the loop or conditional statements that are  available under Bash; you can find these online. Instead, I will give you a short template of a script which does something relevant to network engineering: a script that runs a speed test (upload and download performance) periodically and stores the results in a log file.

Problem Statement

Let’s say you want to measure the upload and download bandwidth of a network once an hour and save the results in a log file for analysis. You can get these measurements on any device by going to speedtest.net and running a test. Obviously, it’s not possible to have somebody do this once an hour and log the results for you.

To solve this problem we’ll need three things:

  1. Run this bandwidth test on the command line
  2. Automate this through a bash script
  3. Log the results in a file

Speedtest Command

There are a few ways to measure upload and download speed. One of the simplest and easiest ways is to use the command “speedtest-cli,” which is a command-line version of the Ookla speedtest.net service. To install the command type:

apt-get install speedtest-cli

Here is what the output of the speedtest command looks like:

netbeez.net$ speedtest-cli
Retrieving speedtest.net configuration...
Testing from AT&T U-verse (99.35.xxx.xxx)...
Retrieving speedtest.net server list...
Selecting best server based on ping...
Hosted by Mimosa Networks (San Jose, CA) [5.00 km]: 33.185 ms
Testing download speed.................................................
Download: 61.03 Mbit/s
Testing upload speed...................................................
Upload: 56.77 Mbit/s

It detected the device’s ISP (AT&T U-verse) and public IP (99.35.xxx.xxx). Then it found a close by server hosted by Mimosa Networks with latency 33.185 ms and 5.00 km away. And then it measured the download and upload speeds.

Pseudocode

Before writing any code let’s think about the logic of our bash script. I believe it’s easy to understand the following pseudocode that corresponds to the problem statement above:

Loop forever
	Run speedtest
	Log results in a file
	Wait for 1 hour
End Loop

The Bash Script

The actual script looks like this:

#!/bin/bash

while true ;
do
    echo "Speedtest running..."
    speedtest-cli --csv >> /home/pi/speedtest.log
    echo "Speedtest finished..."
    sleep 3600
done

Let’s break it down:

Line 1: this is called a shebang and tells the operating system what shell is used for the commands in the script. In this case is Bash.

Line 3: “while” is a construct that can form loops. Whether the loop is executed or not depends on the condition after the “while.” In this case I hardcoded that condition to “true’ so the loop will execute for ever. As an example of another while condition “while [ “$SECONDS” -lt 3 ];” creates a loop that runs up to 3 seconds from the launch of the script (in Bash “$SECONDS” give the elapsed seconds since launch of a script).

Line 4: with the “do” keyword we specify the beginning of the code that will be included in the “while” loop. Together with the “done” on line 9 they specify the beginning and end of the commands included in the loop.

Line 5: This  statement prints the message “Speedtest running…” on the screen. This message and the one “echo “Speedtest finished…”” on line 7 help us know when the speedests starts and finishes.

Line 6: It executes the speedtest command. The option “–csv” prints the results in a comma separated value format. This way I can copy and paste the results in a spreadsheet for further processing or plotting. Since we want to save the results in a file I use the append command “>>” to save the results in file “/home/pi/speedtest.log.”

Line 7: It informs us know that the speedtest finished

Line 8: It sleeps for 3600 seconds, in other words it waits for an hour before reexecuting the loop

Line 9: Specifies the end of the loop commands

Running the Bash Script

I saved the script in a file name speedtest.sh (the “.sh” extension is often used for Bash script files).

To run the script you have two options:

  1. Type “bash speedtest.sh”
  2. Make the script an executable file and then run it with the following commands
    1. chmod +x speetest.sh &
    2. ./speedtest.sh &

To keep the script running after you logout you have to run it in the background with the ampersand “&” at the end. If you don’t use the ampersand the script will die as soon as you logout from the command line session.

Results

Here is what the saved results in “/home/pi/speedtest.log” file look like:

15786,Sprint,"San Jose, CA",2019-02-08T13:43:31.750863,4.999517067446166,23.711,60984225.45806886,58109588.13425905
15786,Sprint,"San Jose, CA",2019-02-08T14:43:31.671134,4.999517067446166,23.164,60679590.74250431,57577721.093844764
15786,Sprint,"San Jose, CA",2019-02-08T15:43:31.684526,4.999517067446166,23.709,60143029.846998245,55949873.806514
15786,Sprint,"San Jose, CA",2019-02-08T16:43:31.903816,4.999517067446166,33.672,40727914.57317653,56387690.64598046

Let’s explain each field of the first line:

Field 1 (15786): the ID of the Ookla server used for the test

Field 2 (Sprint,”San Jose, CA): who hosts the Ookla server

Field 3 (2019-02-08T13:43:31.750863): the UTC date and time the test was executed

Field 4 (4.999517067446166): the distance in km to the Ookla server

Field 5 (23.711): the latency to the Ookla server

Field 6 (60984225.45806886): download speed in bps

Field 7 (58109588.13425905): upload speed in bps

I hope that you will find this script useful and easy enough to try it on your one Linux box. If you have a Raspberry Pi lying around in a drawer, you can put it work by doing something useful. And when your ISP doesn’t deliver the bandwidth you are paying for, you have proof 🙂

decoration image

Get your free trial now

Monitor your network from the user perspective

You can share

Twitter Linkedin Facebook

Let's keep in touch

decoration image