Bash Script: Calculate before/after 2: Calculate Harder

As an update, or an evolution of my earlier script that did some simple math for me, I’ve made one that will full-on test a URL while I’m making changes to see what the impact performance is of my updates.

$ abtesturl.sh --url=https://example.com/ --count=10
Press any key to run initial tests...
Initial average TTFB: 3.538 seconds
Press any key to re-run tests...

Running second test...
Second average TTFB: 1.975 seconds
Before TTFB: 3.538 seconds
After TTFB: 1.975 seconds
Change in TTFB: -1.563 seconds
Percentage Change: -44.00%Code language: JavaScript (javascript)

It makes it much simpler to gather data to write reports or figure out of a change is worth the effort.

Well, that’s about it so here’s the script:

#!/bin/bash

function show_usage() {
	echo "Usage: $0 --url=<URL> [--count=<number of requests>]"
	echo "  --url        Specifies the URL to test."
	echo "  --count      Optional. Specifies the number of requests to send. Default is 6."
	echo
	echo "Example: $0 --url=https://example.com/ --count=5"
	exit
}

function average_ttfb() {
	local URL=""
	local COUNT=6 # Default COUNT to 6 if not supplied
	local CURL_OPTS="-s"

	# Parse arguments
	for arg in "$@"; do
		case $arg in
			--url=*)
			URL="${arg#*=}"
			shift # Remove argument from processing
			;;
		--count=*)
			COUNT="${arg#*=}"
			shift # Remove argument from processing
			;;
		*)
			# Unknown option
			;;
		esac
	done

	if [[ -z "$URL" ]]; then
		exit 1
	fi

	local total_time=0
	local count_success=0

	for ((i=1; i<=COUNT; i++))
	do
		# Perform the curl command, extracting the time to first byte
		ttfb=$(curl $CURL_OPTS -o /dev/null -w "%{time_starttransfer}\n" $URL)
		
		# Check if the curl command was successful
		if [ $? -eq 0 ]; then
			total_time=$(echo "$total_time + $ttfb" | bc)
			((count_success++))
		else
			echo "Request $i failed." >&2
		fi
	done

	if [ $count_success -eq 0 ]; then
		echo "All requests failed." >&2
		return 1
	fi

	# Calculate the average TTFB
	average_time=$(echo "scale=3; $total_time / $count_success" | bc)
	echo $average_time # This line now simply outputs the average time
}

function ab_test_ttfb() {
	# Run initial test
	read -p "Press any key to run initial tests..." -n 1 -r
	initial_ttfb=$(set -e; average_ttfb "$@"; set +e)
	echo "Initial average TTFB: $initial_ttfb seconds"
	
	# Wait for user input to proceed
	read -p "Press any key to re-run tests..." -n 1 -r
	echo # Move to a new line

	# Run second test
	echo "Running second test..."
	second_ttfb=$(average_ttfb "$@")
	echo "Second average TTFB: $second_ttfb seconds"

	# Calculate and output the difference and percentage change
	difference=$(echo "$second_ttfb - $initial_ttfb" | bc)
	percent_change=$(echo "scale=2; ($difference / $initial_ttfb) * 100" | bc)

	echo "Before TTFB: $initial_ttfb seconds"
	echo "After TTFB: $second_ttfb seconds"
	echo "Change in TTFB: $difference seconds"
	echo "Percentage Change: $percent_change%"
}

# Check if help is requested or no arguments are provided
if [[ " $* " == *" --help "* ]] || [[ "$#" -eq 0 ]]; then
	show_usage
fi

# Check if --url is in the arguments
url_present=false
for arg in "$@"; do
	if [[ $arg == --url=* ]]; then
		url_present=true
		break
	fi
done

if [ "$url_present" = false ]; then
	echo "Error: --url argument is required."
	show_usage
fi

ab_test_ttfb "$@"Code language: Bash (bash)

Don’t break anything!

Other Posts Not Worth Reading

Hey, You!

Like this kind of garbage? Subscribe for more! I post like once a month or so, unless I found something interesting to write about.