Build Your Own Traceroute Tool with Bash

Sometimes the best way to understand a tool is to build it yourself.
Introduction
Every Linux user eventually finds themselves troubleshooting a network problem. One of the first tools you'll probably reach for is traceroute, but what happens when it isn't installed, or you don't have permission to install it?
I've found myself in exactly that situation.
Rather than giving up or waiting for someone else to install the package, I decided to build a lightweight alternative using nothing more than Bash and tools that were already available on the system.
Will it replace the real traceroute? No.
Will it help you understand how traceroute works under the hood? Absolutely.
That's what this article is about.
How Traceroute Works
At its core, traceroute is surprisingly simple.
Every IP packet contains a value called Time To Live (TTL). Despite the name, TTL isn't measured in seconds. It's simply a counter that is reduced by one every time the packet passes through a router.
When that counter reaches zero, the router discards the packet and sends an ICMP Time Exceeded message back to the sender.
Traceroute takes advantage of this behaviour.
It starts by sending a packet with a TTL of 1. The first router drops it and replies with its address.
Next it sends another packet with a TTL of 2. This time the packet gets one hop further before expiring.
By increasing the TTL one hop at a time, traceroute gradually reveals every router between you and the destination until the packet finally reaches its target.
It's a clever idea that's been around for decades, and it's still one of the quickest ways to understand what's happening across a network.
Why Build Your Own?
There are a few practical reasons.
Perhaps you're working on a locked-down server where installing packages isn't an option.
Maybe you're studying networking and want to understand what traceroute is actually doing instead of treating it like a black box.
Or perhaps you just enjoy building things.
For me, it was a combination of all three.
Let's Build It
Create a new file called simple_trace.sh and start with the usual shebang:
#!/bin/bash
Next, make sure the user supplies the destination IP address:
if [ "$#" -ne 1 ]; then
echo "Usage: $0 target_ip_address"
exit 1
fi
Now define a few variables that we'll use throughout the script:
TARGET_IP="$1"
MAX_HOPS=30
TTL=1
The main loop is where the magic happens.
For each iteration we send a single ICMP echo request using the current TTL value, extract the responding IP address and round-trip time, display the result, then increment the TTL before trying again.
while [ $TTL -le $MAX_HOPS ]; do
OUTPUT=$(ping -c 1 -t $TTL $TARGET_IP)
IP=$(echo "$OUTPUT" | grep -Eo "From [0-9.]* " | awk '{print $2}')
RTT=$(echo "$OUTPUT" | grep -Eo "time=[0-9.]* ms" | awk -F= '{print $2}')
if [ -n "$IP" ]; then
echo "$TTL: $IP $RTT"
else
echo "$TTL: *"
fi
if [ "$IP" == "$TARGET_IP" ]; then
break
fi
TTL=$((TTL + 1))
done
Once you've saved the file, make it executable:
chmod +x simple_trace.sh
You can then run it like this:
./simple_trace.sh target_ip_address
Testing Your Script
Try tracing a host you know is reachable.
./simple_trace.sh target_ip_address
Once you've done that, compare the output with the standard traceroute command on a system where it's available.
You'll notice that your script is much simpler and doesn't provide every feature that the real utility offers, but that's completely fine. The goal isn't to replace traceroute. The goal is to understand the principles behind it.
Where You Could Take It Next
If you're looking for a challenge, here are a few ideas:
- Resolve hostnames instead of displaying only IP addresses.
- Measure and display packet loss.
- Support IPv6.
- Allow the user to specify the maximum number of hops.
- Add better timeout handling.
- Make the output look more like the real
traceroutecommand.
Each improvement teaches you something new about networking, Bash, or both.
Final Thoughts
One of my favourite ways to learn is to recreate tools I use every day.
It forces me to stop thinking of them as magic and start understanding the ideas that make them work.
This script isn't intended to replace traceroute, and it certainly isn't as feature-rich. But if it helps you understand TTL, ICMP, and how packets move through a network, then it's done its job.
If you decide to extend it, I'd love to hear what you add.
Happy hacking!
Note: The images used in this article were generated using AI.