Introduction to ping
The ping command is one of the most fundamental network troubleshooting tools. It sends ICMP (Internet Control Message Protocol) Echo Request packets to a target host and waits for Echo Reply packets. This allows you to test network connectivity, measure round-trip time, and check packet loss.
Key Concepts
- ICMP Protocol: Uses Internet Control Message Protocol for network diagnostics
- Round-Trip Time (RTT): Time taken for packet to travel to destination and back
- Packet Loss: Percentage of packets that don't receive a reply
- TTL (Time To Live): Limits packet's lifetime in the network
- Network Latency: Delay in network communication
1. Basic Usage
Simple ping Commands
# Basic ping (continues until Ctrl+C) ping google.com ping 8.8.8.8 # Ping with count limit ping -c 4 google.com ping -c 10 192.168.1.1 # Ping with interval ping -i 2 google.com # 2 second interval # Ping localhost (self-test) ping localhost ping 127.0.0.1 # Examples $ ping -c 4 google.com # PING google.com (142.250.185.78): 56 data bytes # 64 bytes from 142.250.185.78: icmp_seq=0 ttl=115 time=14.2 ms # 64 bytes from 142.250.185.78: icmp_seq=1 ttl=115 time=14.5 ms # 64 bytes from 142.250.185.78: icmp_seq=2 ttl=115 time=14.1 ms # 64 bytes from 142.250.185.78: icmp_seq=3 ttl=115 time=14.3 ms # # --- google.com ping statistics --- # 4 packets transmitted, 4 packets received, 0% packet loss # round-trip min/avg/max/stddev = 14.1/14.3/14.5/0.2 ms
Common Use Cases
# Check internet connectivity ping -c 4 8.8.8.8 # Check local network ping -c 4 192.168.1.1 # Test DNS resolution ping -c 2 google.com # Quick network status if ping -c 1 google.com >/dev/null 2>&1; then echo "Internet is up" else echo "Internet is down" fi # Continuous monitoring ping -i 5 google.com > ping.log & # Check specific port (using tcping or nping) # Note: Standard ping doesn't use ports tcping google.com 80 # Requires tcping utility
2. Command Options
-c (Count) Option
# Send specific number of packets
ping -c 5 google.com
ping -c 100 192.168.1.1
# Use in scripts
PACKET_LOSS=$(ping -c 10 -q google.com | grep -oP '\d+(?=% packet loss)')
if [ "$PACKET_LOSS" -gt 5 ]; then
echo "Warning: High packet loss: $PACKET_LOSS%"
fi
# Progressive testing
test_connectivity() {
local host="$1"
local max_packets="${2:-4}"
echo "Testing connection to $host..."
for count in 1 2 4 8; do
if [ $count -gt $max_packets ]; then
break
fi
echo -n "Sending $count packets: "
ping -c $count -q "$host" >/dev/null 2>&1 && echo "OK" || echo "FAILED"
done
}
-i (Interval) Option
# Set interval between packets
ping -i 2 google.com # 2 seconds between pings
ping -i 0.2 google.com # 200ms between pings (requires root)
# Flood ping (very fast, requires root)
sudo ping -f google.com # Flood ping
sudo ping -i 0.001 google.com # 1000 pings per second
# Adaptive interval for monitoring
monitor_with_backoff() {
local host="$1"
local interval=1
while true; do
if ping -c 1 -W 2 "$host" >/dev/null 2>&1; then
echo "$(date): $host is up"
interval=1
else
echo "$(date): $host is down"
interval=$((interval * 2))
[ $interval -gt 60 ] && interval=60
fi
sleep $interval
done
}
-W (Timeout) and -w (Deadline) Options
# -W: Time to wait for response (seconds)
ping -c 1 -W 2 google.com # Wait 2 seconds for response
# -w: Overall deadline (seconds)
ping -w 10 google.com # Stop after 10 seconds regardless of count
# -W: Timeout for each response
timeout_test() {
local host="$1"
local timeout="${2:-2}"
echo "Testing $host with ${timeout}s timeout"
if ping -c 1 -W "$timeout" "$host" >/dev/null 2>&1; then
echo "✓ $host responded within ${timeout}s"
else
echo "✗ $host timeout after ${timeout}s"
fi
}
# Deadline example
collect_samples() {
local host="$1"
local duration="$2"
local output="/tmp/ping_${host}_$(date +%s).log"
echo "Collecting ping samples for $duration seconds"
ping -w "$duration" "$host" > "$output"
echo "Results saved to $output"
}
-s (Packet Size) Option
# Set packet size (default 56 bytes + 8 byte ICMP header = 64 bytes)
ping -s 100 google.com # 100 byte payload
ping -s 1472 google.com # Max for standard Ethernet (1500 MTU - 28)
ping -s 65507 google.com # Maximum possible
# MTU discovery
find_mtu() {
local host="$1"
local mtu=1500
while [ $mtu -gt 500 ]; do
echo -n "Testing MTU $mtu: "
if ping -c 1 -s $((mtu - 28)) -M do "$host" >/dev/null 2>&1; then
echo "OK"
echo "Maximum MTU: $mtu"
break
else
echo "Failed"
mtu=$((mtu - 10))
fi
done
}
# Jumbo frame test
test_jumbo_frames() {
local host="$1"
local sizes=(1500 4470 9000)
for size in "${sizes[@]}"; do
echo -n "Testing $size byte packets: "
if ping -c 3 -s $((size - 28)) -M do "$host" >/dev/null 2>&1; then
echo "✓ Supported"
else
echo "✗ Not supported"
fi
done
}
-t (TTL) Option
# Set Time To Live
ping -t 64 google.com # Set TTL to 64
ping -t 1 localhost # TTL 1 - won't leave the machine
ping -t 2 192.168.1.1 # TTL 2 - may reach local router
# TTL tracing
trace_ttl() {
local host="$1"
local max_hops="${2:-30}"
for ttl in $(seq 1 $max_hops); do
echo -n "Hop $ttl: "
ping -c 1 -t $ttl -W 1 "$host" 2>&1 | head -1
done
}
# Determine distance by TTL
estimate_hops() {
local host="$1"
local initial_ttl=$(ping -c 1 "$host" | grep -o 'ttl=[0-9]*' | cut -d= -f2)
if [ -n "$initial_ttl" ]; then
# Common starting TTL values: 64, 128, 255
if [ $initial_ttl -gt 128 ]; then
hops=$((255 - initial_ttl))
elif [ $initial_ttl -gt 64 ]; then
hops=$((128 - initial_ttl))
else
hops=$((64 - initial_ttl))
fi
echo "Approximately $hops hops away"
fi
}
3. Practical Examples
Network Monitoring Script
#!/bin/bash
# Comprehensive network monitor
monitor_network() {
local hosts=("8.8.8.8" "1.1.1.1" "google.com" "localhost")
local log="/var/log/network_monitor.log"
local alert_email="admin@localhost"
while true; do
timestamp=$(date '+%Y-%m-%d %H:%M:%S')
for host in "${hosts[@]}"; do
# Get ping statistics
stats=$(ping -c 5 -q "$host" 2>/dev/null | tail -2)
if [ $? -eq 0 ]; then
# Extract packet loss
loss=$(echo "$stats" | grep -oP '\d+(?=% packet loss)')
# Extract average RTT
avg=$(echo "$stats" | grep -oP '(?<=avg = )[0-9.]+')
echo "$timestamp - $host: loss=${loss}%, avg=${avg}ms" >> "$log"
# Alert on high loss
if [ "$loss" -gt 20 ]; then
echo "High packet loss to $host: ${loss}%" | \
mail -s "Network Alert" "$alert_email"
fi
# Alert on high latency
if [ -n "$avg" ] && [ "${avg%.*}" -gt 200 ]; then
echo "High latency to $host: ${avg}ms" | \
mail -s "Network Alert" "$alert_email"
fi
else
echo "$timestamp - $host: DOWN" >> "$log"
echo "Host $host is down" | mail -s "Network Alert" "$alert_email"
fi
done
sleep 60 # Check every minute
done
}
# Start monitor in background
# monitor_network &
Connectivity Tester
#!/bin/bash
# Comprehensive connectivity test
test_connectivity() {
local test_file="/tmp/connectivity_test_$(date +%Y%m%d_%H%M%S).txt"
{
echo "Network Connectivity Test - $(date)"
echo "======================================"
echo
# Test 1: Local interface
echo "1. Testing local interface:"
if ping -c 2 -W 2 127.0.0.1 >/dev/null 2>&1; then
echo " ✓ Loopback is working"
else
echo " ✗ Loopback failed - network stack issue"
fi
echo
# Test 2: Default gateway
echo "2. Testing default gateway:"
gateway=$(ip route | grep default | awk '{print $3}')
if [ -n "$gateway" ]; then
if ping -c 2 -W 2 "$gateway" >/dev/null 2>&1; then
echo " ✓ Gateway $gateway is reachable"
else
echo " ✗ Gateway $gateway is unreachable"
fi
else
echo " ✗ No default gateway found"
fi
echo
# Test 3: DNS resolution
echo "3. Testing DNS resolution:"
for dns in 8.8.8.8 1.1.1.1; do
if ping -c 2 -W 2 "$dns" >/dev/null 2>&1; then
echo " ✓ DNS server $dns is reachable"
else
echo " ✗ DNS server $dns is unreachable"
fi
done
echo
# Test 4: External connectivity
echo "4. Testing external connectivity:"
for host in google.com amazon.com; do
result=$(ping -c 2 -W 3 "$host" 2>&1)
if [ $? -eq 0 ]; then
rtt=$(echo "$result" | grep avg | cut -d/ -f5)
echo " ✓ $host reachable (avg RTT: ${rtt}ms)"
else
echo " ✗ $host unreachable"
fi
done
echo
# Test 5: Packet loss
echo "5. Testing packet loss (10 packets):"
for host in 8.8.8.8 google.com; do
output=$(ping -c 10 -q "$host" 2>&1)
loss=$(echo "$output" | grep -oP '\d+(?=% packet loss)')
echo " $host: ${loss}% loss"
done
} | tee "$test_file"
echo -e "\nResults saved to: $test_file"
}
# Run test
test_connectivity
Latency Benchmark
#!/bin/bash
# Network latency benchmark
benchmark_latency() {
local host="$1"
local samples="${2:-100}"
local output="/tmp/latency_${host}_$(date +%s).txt"
echo "Benchmarking latency to $host with $samples samples"
echo "==================================================="
# Collect samples
ping -c "$samples" -i 0.2 "$host" > "$output"
# Extract RTT values
rtts=$(grep -o 'time=[0-9.]*' "$output" | cut -d= -f2)
# Calculate statistics
min=$(echo "$rtts" | sort -n | head -1)
max=$(echo "$rtts" | sort -n | tail -1)
avg=$(echo "$rtts" | awk '{sum+=$1} END {print sum/NR}')
# Calculate jitter (variation in latency)
prev=0
jitter_sum=0
count=0
for rtt in $rtts; do
if [ $prev -ne 0 ]; then
diff=$(echo "$rtt - $prev" | bc | sed 's/-//')
jitter_sum=$(echo "$jitter_sum + $diff" | bc)
count=$((count + 1))
fi
prev=$rtt
done
jitter=$(echo "scale=2; $jitter_sum / $count" | bc)
# Display results
cat << EOF
Latency Statistics for $host
============================
Samples: $samples
Minimum RTT: ${min}ms
Maximum RTT: ${max}ms
Average RTT: ${avg}ms
Jitter: ${jitter}ms
Distribution:
EOF
# Create simple distribution
echo "$rtts" | awk '
{
if ($1 < 10) low++
else if ($1 < 20) medium++
else if ($1 < 50) high++
else extreme++
}
END {
printf "<10ms: %d\n", low
printf "10-20ms: %d\n", medium
printf "20-50ms: %d\n", high
printf ">50ms: %d\n", extreme
}'
rm "$output"
}
# Usage
# benchmark_latency google.com 200
4. Scripting with ping
Network Status Functions
#!/bin/bash
# Check if host is up
is_host_up() {
local host="$1"
local timeout="${2:-2}"
ping -c 1 -W "$timeout" "$host" >/dev/null 2>&1
}
# Wait for host to come up
wait_for_host() {
local host="$1"
local timeout="${2:-60}"
local interval="${3:-5}"
local elapsed=0
echo -n "Waiting for $host to come up"
while [ $elapsed -lt $timeout ]; do
if is_host_up "$host"; then
echo -e "\n$host is up after ${elapsed}s"
return 0
fi
echo -n "."
sleep $interval
elapsed=$((elapsed + interval))
done
echo -e "\nTimeout waiting for $host"
return 1
}
# Get average RTT
get_avg_rtt() {
local host="$1"
local samples="${2:-4}"
ping -c "$samples" "$host" 2>/dev/null |
grep avg |
cut -d/ -f5 |
sed 's/ms//'
}
# Get packet loss percentage
get_packet_loss() {
local host="$1"
local samples="${2:-10}"
ping -c "$samples" -q "$host" 2>/dev/null |
grep -oP '\d+(?=% packet loss)' || echo "100"
}
# Quality score (0-100)
network_quality_score() {
local host="$1"
loss=$(get_packet_loss "$host" 20)
rtt=$(get_avg_rtt "$host" 5)
# Score based on RTT and packet loss
if [ "$loss" -gt 20 ]; then
echo "0"
elif [ "$loss" -gt 10 ]; then
echo "25"
elif [ "$loss" -gt 5 ]; then
echo "50"
elif [ -z "$rtt" ]; then
echo "0"
else
if [ "$(echo "$rtt < 20" | bc)" -eq 1 ]; then
echo "100"
elif [ "$(echo "$rtt < 50" | bc)" -eq 1 ]; then
echo "80"
elif [ "$(echo "$rtt < 100" | bc)" -eq 1 ]; then
echo "60"
else
echo "40"
fi
fi
}
Continuous Monitoring
#!/bin/bash
# Monitor multiple hosts
monitor_hosts() {
local hosts=("$@")
local log="/var/log/ping_monitor.log"
while true; do
timestamp=$(date '+%Y-%m-%d %H:%M:%S')
for host in "${hosts[@]}"; do
if ping -c 1 -W 2 "$host" >/dev/null 2>&1; then
rtt=$(ping -c 1 "$host" 2>/dev/null | grep time= | cut -d= -f4)
status="UP (${rtt})"
else
status="DOWN"
# Alert on failure
logger -t ping_monitor "Host $host is down"
# Optional email alert
if [ -f /usr/bin/mail ]; then
echo "$host is down at $timestamp" | \
mail -s "Host Down Alert" admin@localhost
fi
fi
echo "$timestamp - $host: $status" >> "$log"
done
sleep 60
done
}
# Generate report from logs
generate_report() {
local logfile="${1:-/var/log/ping_monitor.log}"
local hours="${2:-24}"
echo "Ping Monitor Report - $(date)"
echo "==============================="
echo
# Get unique hosts from log
hosts=$(cut -d' ' -f4 "$logfile" | sort -u)
for host in $hosts; do
echo "Host: $host"
echo " Total checks: $(grep -c "$host" "$logfile")"
echo " Failures: $(grep -c "$host.*DOWN" "$logfile")"
# Calculate uptime
total=$(grep -c "$host" "$logfile")
failed=$(grep -c "$host.*DOWN" "$logfile")
uptime=$(( (total - failed) * 100 / total ))
echo " Uptime: ${uptime}%"
# Average RTT
avg_rtt=$(grep "$host.*UP" "$logfile" |
grep -o 'time=[0-9.]*' |
cut -d= -f2 |
awk '{sum+=$1} END {print sum/NR}')
echo " Avg RTT: ${avg_rtt}ms"
echo
done
}
5. Advanced Techniques
Ping with Timestamp
#!/bin/bash
# Ping with timestamp
ping_with_time() {
local host="$1"
shift
ping "$@" "$host" | while read line; do
echo "$(date '+%Y-%m-%d %H:%M:%S') - $line"
done
}
# Log to file with rotation
ping_logger() {
local host="$1"
local logbase="${2:-/var/log/ping}"
local max_size="${3:-10485760}" # 10MB
while true; do
logfile="${logbase}_$(date +%Y%m%d).log"
ping_with_time "$host" >> "$logfile"
# Check size and rotate if needed
if [ -f "$logfile" ] && [ "$(stat -c%s "$logfile")" -gt "$max_size" ]; then
mv "$logfile" "${logfile}.old"
fi
sleep 1
done
}
# Ping with weather report
ping_with_weather() {
local host="$1"
ping "$host" | while read line; do
if [[ $line == *"time="* ]]; then
rtt=$(echo "$line" | grep -o 'time=[0-9.]*' | cut -d= -f2)
if [ "$(echo "$rtt < 10" | bc)" -eq 1 ]; then
weather="☀️ Excellent"
elif [ "$(echo "$rtt < 50" | bc)" -eq 1 ]; then
weather="⛅ Good"
elif [ "$(echo "$rtt < 100" | bc)" -eq 1 ]; then
weather="☁️ Fair"
elif [ "$(echo "$rtt < 200" | bc)" -eq 1 ]; then
weather="🌧️ Poor"
else
weather="⛈️ Terrible"
fi
echo "$line - $weather"
else
echo "$line"
fi
done
}
Graphing Ping Data
#!/bin/bash
# Create simple ASCII graph of ping times
ping_graph() {
local host="$1"
local count="${2:-20}"
local width="${3:-50}"
echo "Ping Graph for $host"
echo "====================="
# Collect ping times
times=()
for i in $(seq 1 $count); do
output=$(ping -c 1 "$host" 2>/dev/null)
if [ $? -eq 0 ]; then
time=$(echo "$output" | grep -o 'time=[0-9.]*' | cut -d= -f2)
times+=($time)
else
times+=(-1)
fi
sleep 0.5
done
# Find max time for scaling
max_time=0
for t in "${times[@]}"; do
if [ "$(echo "$t > $max_time" | bc)" -eq 1 ]; then
max_time=$t
fi
done
# Draw graph
for i in "${!times[@]}"; do
t=${times[$i]}
if [ "$t" == "-1" ]; then
printf "%3d: %s\n" $((i+1)) "❌"
else
bar_length=$(echo "scale=0; $t * $width / $max_time" | bc)
bar=$(printf "%${bar_length}s" | tr ' ' '█')
printf "%3d: %3.1fms %s\n" $((i+1)) "$t" "$bar"
fi
done
}
# Generate CSV for external graphing
ping_to_csv() {
local host="$1"
local duration="${2:-60}"
local interval="${3:-1}"
local output="ping_${host}_$(date +%s).csv"
echo "timestamp,rtt_ms,status" > "$output"
end=$((SECONDS + duration))
while [ $SECONDS -lt $end ]; do
ts=$(date +%s)
output_line=$(ping -c 1 -W 1 "$host" 2>&1)
if [ $? -eq 0 ]; then
rtt=$(echo "$output_line" | grep -o 'time=[0-9.]*' | cut -d= -f2)
echo "$ts,$rtt,up" >> "$output"
else
echo "$ts,-1,down" >> "$output"
fi
sleep "$interval"
done
echo "Data saved to $output"
}
6. Special Ping Types
Broadcast Ping
#!/bin/bash
# Broadcast ping (discover hosts on network)
discover_hosts() {
local network="${1:-192.168.1}"
local timeout="${2:-1}"
echo "Discovering hosts on ${network}.0/24"
echo "==================================="
for i in {1..254}; do
(
if ping -c 1 -W "$timeout" "${network}.${i}" >/dev/null 2>&1; then
echo "Host ${network}.${i} is up"
fi
) &
# Limit concurrent processes
if [ $((i % 20)) -eq 0 ]; then
wait
fi
done
wait
}
# Fast network scan
fast_scan() {
local network="${1:-192.168.1}"
local timeout="${2:-1}"
local output="/tmp/hosts_$(date +%s).txt"
echo "Fast scanning ${network}.0/24"
seq 1 254 | xargs -P 50 -I {} sh -c "
if ping -c 1 -W $timeout ${network}.{} >/dev/null 2>&1; then
echo ${network}.{} >> $output
fi
"
echo "Found $(wc -l < "$output") hosts:"
sort -n "$output"
rm "$output"
}
IPv6 Ping
#!/bin/bash
# IPv6 ping (ping6 on some systems)
ping6_test() {
local host="$1"
# Use appropriate ping command
if command -v ping6 >/dev/null 2>&1; then
ping6 -c 4 "$host"
else
ping -6 -c 4 "$host"
fi
}
# Test IPv6 connectivity
test_ipv6() {
local hosts=("ipv6.google.com" "google.com" "2001:4860:4860::8888")
echo "IPv6 Connectivity Test"
echo "======================"
# Check if IPv6 is enabled
if ! ip -6 addr show | grep -q inet6; then
echo "IPv6 is not configured on this system"
return 1
fi
for host in "${hosts[@]}"; do
echo -n "Testing $host: "
if ping6_test "$host" >/dev/null 2>&1; then
echo "✓ Reachable"
else
echo "✗ Unreachable"
fi
done
}
7. Error Handling and Edge Cases
Robust Ping Function
#!/bin/bash
# Robust ping with error handling
robust_ping() {
local host="$1"
local timeout="${2:-5}"
local max_retries="${3:-3}"
local retry=0
# Validate input
if [ -z "$host" ]; then
echo "Error: No host specified" >&2
return 2
fi
# Check if hostname resolves
if ! host "$host" >/dev/null 2>&1; then
echo "Warning: $host may not resolve" >&2
fi
while [ $retry -lt $max_retries ]; do
if ping -c 1 -W "$timeout" "$host" >/dev/null 2>&1; then
return 0
fi
retry=$((retry + 1))
[ $retry -lt $max_retries ] && sleep 1
done
return 1
}
# Ping with fallback
ping_with_fallback() {
local primary="$1"
local fallback="$2"
if robust_ping "$primary"; then
echo "Using primary host: $primary"
return 0
elif [ -n "$fallback" ] && robust_ping "$fallback"; then
echo "Primary failed, using fallback: $fallback"
return 0
else
echo "Both primary and fallback are unreachable" >&2
return 1
fi
}
# Handle different error conditions
ping_error_handler() {
local host="$1"
output=$(ping -c 1 "$host" 2>&1)
case $? in
0)
echo "Success"
;;
1)
if echo "$output" | grep -q "unknown host"; then
echo "DNS resolution failed"
elif echo "$output" | grep -q "Network is unreachable"; then
echo "Network is unreachable"
elif echo "$output" | grep -q "Destination Host Unreachable"; then
echo "Destination host unreachable"
else
echo "Ping failed with unknown error"
fi
;;
2)
echo "Invalid host or command usage"
;;
esac
}
8. Integration with Other Tools
With traceroute
#!/bin/bash
# Combined ping and traceroute
ping_trace() {
local host="$1"
echo "Network Analysis for $host"
echo "==========================="
echo
# First ping test
echo "PING Test:"
ping -c 4 "$host"
echo
# Then traceroute
echo "TRACEROUTE:"
traceroute "$host"
}
# Path quality check
check_path_quality() {
local host="$1"
local threshold="${2:-100}" # ms threshold
# Get number of hops
hops=$(traceroute -n "$host" 2>/dev/null | tail -n +2 | wc -l)
# Get average RTT
rtt=$(ping -c 10 -q "$host" 2>/dev/null | grep avg | cut -d/ -f5)
echo "Path to $host: $hops hops, avg RTT ${rtt}ms"
if [ "$(echo "$rtt / $hops > 10" | bc)" -eq 1 ]; then
echo "High per-hop latency detected"
fi
}
With network configuration
#!/bin/bash
# Check all network interfaces
check_interfaces() {
for interface in $(ip link show | grep -o '^[0-9]: [^:]*' | cut -d' ' -f2); do
echo "Interface: $interface"
# Get IP address
ip=$(ip addr show "$interface" 2>/dev/null | grep -o 'inet [0-9.]*' | cut -d' ' -f2)
if [ -n "$ip" ]; then
echo " IP: $ip"
# Ping gateway if available
gateway=$(ip route show dev "$interface" | grep default | awk '{print $3}')
if [ -n "$gateway" ]; then
echo -n " Gateway $gateway: "
if ping -c 1 -W 1 "$gateway" >/dev/null 2>&1; then
echo "✓ Reachable"
else
echo "✗ Unreachable"
fi
fi
else
echo " No IP address"
fi
echo
done
}
# Test DNS servers
test_dns() {
local dns_servers=("8.8.8.8" "1.1.1.1" "9.9.9.9")
echo "Testing DNS Server Connectivity"
echo "==============================="
for dns in "${dns_servers[@]}"; do
echo -n "$dns: "
if ping -c 2 -W 2 "$dns" >/dev/null 2>&1; then
rtt=$(ping -c 4 -q "$dns" | grep avg | cut -d/ -f5)
echo "✓ Reachable (avg ${rtt}ms)"
else
echo "✗ Unreachable"
fi
done
}
9. Performance and Optimization
Load Testing
#!/bin/bash
# Load test a network
load_test() {
local host="$1"
local duration="${2:-10}"
local rate="${3:-100}" # packets per second
echo "Load testing $host for $duration seconds at $rate pps"
echo "======================================================="
# Calculate interval
interval=$(echo "scale=3; 1 / $rate" | bc)
# Run test
sudo ping -i "$interval" -w "$duration" -f "$host" 2>&1 | while read line; do
if [[ $line == *"statistics"* ]]; then
echo "Test complete"
break
fi
done
}
# Measure maximum throughput
max_throughput() {
local host="$1"
local packet_sizes=(64 128 256 512 1024 1472)
echo "Maximum Throughput Test"
echo "======================="
echo "Packet Size Throughput"
echo "------------------------"
for size in "${packet_sizes[@]}"; do
# Send 100 packets at max rate
output=$(sudo ping -f -c 100 -s "$size" "$host" 2>&1)
# Extract time
time=$(echo "$output" | grep "time" | grep -o '[0-9.]* ms' | cut -d' ' -f1)
if [ -n "$time" ]; then
# Calculate throughput (packet size * 100 / time in seconds)
throughput=$(echo "scale=2; $size * 100 * 1000 / $time / 1024" | bc)
printf "%-12d %8.2f KB/s\n" "$size" "$throughput"
fi
done
}
Optimization Script
#!/bin/bash
# Optimize ping parameters for different networks
optimize_ping() {
local host="$1"
echo "Optimizing ping parameters for $host"
echo "===================================="
# Test different packet sizes
echo -e "\nPacket Size Optimization:"
for size in 56 128 256 512 1024 1472; do
rtt=$(ping -c 5 -s "$size" -q "$host" 2>/dev/null | grep avg | cut -d/ -f5)
if [ -n "$rtt" ]; then
echo " Size $size: ${rtt}ms"
fi
done
# Test different intervals
echo -e "\nInterval Optimization:"
for interval in 1.0 0.5 0.2 0.1; do
echo -n " Interval ${interval}s: "
if ping -i "$interval" -c 10 "$host" >/dev/null 2>&1; then
loss=$(ping -i "$interval" -c 100 -q "$host" 2>&1 | grep -oP '\d+(?=% packet loss)')
echo "OK (${loss}% loss)"
else
echo "FAILED"
fi
done
# Recommend optimal settings
echo -e "\nRecommended settings:"
echo " Packet size: 56 bytes (default)"
echo " Interval: 1 second for monitoring"
echo " Count: 4 for quick tests, 100 for quality analysis"
}
10. Real-World Applications
ISP Quality Monitor
#!/bin/bash
# Monitor ISP connection quality
monitor_isp() {
local hosts=("8.8.8.8" "1.1.1.1" "google.com")
local logdir="/var/log/isp_monitor"
local interval=300 # 5 minutes
mkdir -p "$logdir"
while true; do
timestamp=$(date '+%Y%m%d_%H%M%S')
logfile="$logdir/isp_$(date +%Y%m%d).csv"
# Initialize log with headers if new file
if [ ! -f "$logfile" ]; then
echo "timestamp,host,rtt_min,rtt_avg,rtt_max,loss" > "$logfile"
fi
for host in "${hosts[@]}"; do
# Run ping test
output=$(ping -c 20 -q "$host" 2>&1)
if [ $? -eq 0 ]; then
# Parse statistics
stats=$(echo "$output" | grep -A1 statistics | tail -1)
loss=$(echo "$output" | grep -oP '\d+(?=% packet loss)')
rtt=$(echo "$stats" | cut -d/ -f4,5,6)
rtt_min=$(echo "$rtt" | cut -d/ -f1)
rtt_avg=$(echo "$rtt" | cut -d/ -f2)
rtt_max=$(echo "$rtt" | cut -d/ -f3)
echo "$timestamp,$host,$rtt_min,$rtt_avg,$rtt_max,$loss" >> "$logfile"
fi
done
# Generate daily report at midnight
if [ "$(date +%H%M)" = "0000" ]; then
generate_isp_report "$(date -d yesterday +%Y%m%d)"
fi
sleep "$interval"
done
}
# Generate ISP quality report
generate_isp_report() {
local date="$1"
local logfile="/var/log/isp_monitor/isp_${date}.csv"
if [ ! -f "$logfile" ]; then
return
fi
report="/tmp/isp_report_${date}.txt"
{
echo "ISP Quality Report - $date"
echo "==========================="
echo
for host in 8.8.8.8 1.1.1.1 google.com; do
echo "Statistics for $host:"
echo "----------------------"
# Calculate averages
awk -F, -v host="$host" '
$2 == host {
sum_avg += $4
sum_loss += $6
count++
}
END {
printf "Average RTT: %.2f ms\n", sum_avg/count
printf "Average Loss: %.2f%%\n", sum_loss/count
printf "Samples: %d\n", count
}
' "$logfile"
echo
done
# Find worst performance periods
echo "Worst Performance Periods:"
echo "-------------------------"
awk -F, '
NR>1 {
if ($4 > 100 || $6 > 5) {
printf "%s: %s - High RTT/Loss\n", $1, $2
}
}
' "$logfile" | head -10
} > "$report"
echo "Report generated: $report"
}
VPN Connection Monitor
#!/bin/bash
# Monitor VPN connection stability
monitor_vpn() {
local vpn_host="$1"
local normal_host="8.8.8.8"
local log="/var/log/vpn_monitor.log"
while true; do
timestamp=$(date '+%Y-%m-%d %H:%M:%S')
# Test VPN endpoint
vpn_result=$(ping -c 3 -W 2 "$vpn_host" 2>&1)
vpn_status=$?
# Test normal internet
normal_result=$(ping -c 1 -W 2 "$normal_host" 2>&1)
normal_status=$?
# Determine overall status
if [ $vpn_status -eq 0 ] && [ $normal_status -eq 0 ]; then
# Extract RTTs
vpn_rtt=$(echo "$vpn_result" | grep avg | cut -d/ -f5)
normal_rtt=$(echo "$normal_result" | grep time= | cut -d= -f4)
echo "$timestamp - VPN: UP (${vpn_rtt}ms), Internet: UP (${normal_rtt}ms)" >> "$log"
elif [ $vpn_status -eq 0 ] && [ $normal_status -ne 0 ]; then
echo "$timestamp - VPN: UP, Internet: DOWN - Potential DNS issue" >> "$log"
elif [ $vpn_status -ne 0 ] && [ $normal_status -eq 0 ]; then
echo "$timestamp - VPN: DOWN, Internet: UP - VPN disconnected" >> "$log"
# Try to reconnect VPN (adjust based on your VPN)
# systemctl restart openvpn@client
else
echo "$timestamp - VPN: DOWN, Internet: DOWN - Network problem" >> "$log"
fi
sleep 30
done
}
11. Best Practices and Tips
Safe Ping Usage
#!/bin/bash
# Don't flood networks without permission
# Bad:
# ping -f google.com
# Good:
ping -c 10 -i 1 google.com
# Use appropriate timeouts
ping -c 1 -W 2 google.com
# Handle termination gracefully
cleanup_ping() {
local pid=$1
kill $pid 2>/dev/null
wait $pid 2>/dev/null
echo "Ping stopped"
}
# Run ping with timeout
ping_with_timeout() {
local host="$1"
local timeout="$2"
ping "$host" &
local pid=$!
( sleep "$timeout"; cleanup_ping $pid ) &
local watchdog=$!
wait $pid
kill $watchdog 2>/dev/null
}
Performance Tips
#!/bin/bash
# Tips for better ping performance
# 1. Use numeric addresses to avoid DNS
ping -n 8.8.8.8
# 2. Adjust socket buffer for high RTT
sudo sysctl -w net.ipv4.ping_group_range="0 2147483647"
# 3. Use appropriate count for different scenarios
quick_test() { ping -c 4 "$1"; }
quality_test() { ping -c 100 "$1"; }
monitor() { ping -i 5 "$1"; }
# 4. Combine with timeout
ping -c 1 -W 1 "$1" || echo "Host unreachable"
# 5. Use quiet mode for scripts
ping -c 1 -q "$1" >/dev/null && echo "OK"
# 6. Record timestamps for analysis
ping -D google.com | while read line; do
echo "$(date +%s): $line"
done
Common Pitfalls
#!/bin/bash
# Pitfall 1: Firewall blocking ICMP
# Some hosts block ping
test_alternative() {
if ! ping -c 1 "$1" >/dev/null 2>&1; then
echo "Host may block ICMP, trying port 80"
nc -zv -w 2 "$1" 80 2>&1 | grep -q succeeded && echo "Port 80 open"
fi
}
# Pitfall 2: Packet fragmentation
# Test with different sizes
test_fragmentation() {
local host="$1"
local sizes=(1472 1473 2000)
for size in "${sizes[@]}"; do
if ping -c 1 -M do -s "$size" "$host" >/dev/null 2>&1; then
echo "Size $size: OK (fragmentation not required)"
else
echo "Size $size: FAILED (fragmentation required)"
fi
done
}
# Pitfall 3: Interface selection
# Specify interface for multi-homed hosts
ping -I eth0 8.8.8.8
ping -I wlan0 8.8.8.8
# Pitfall 4: High latency expectations
# Set appropriate timeouts for long links
ping -W 10 slow-server.com
# Pitfall 5: Packet loss interpretation
# Single packet loss doesn't indicate problem
interpret_loss() {
local loss=$1
if [ "$loss" -eq 0 ]; then
echo "Excellent"
elif [ "$loss" -lt 1 ]; then
echo "Good"
elif [ "$loss" -lt 5 ]; then
echo "Fair"
else
echo "Poor"
fi
}
12. Command Summary and Cheat Sheet
Quick Reference
# Basic commands ping host # Continuous ping (Ctrl+C to stop) ping -c 4 host # Send 4 packets ping -i 2 host # 2 second interval ping -W 2 host # 2 second timeout ping -s 100 host # 100 byte packets # Advanced options ping -f host # Flood ping (root) ping -D host # Print timestamps ping -q host # Quiet output ping -R host # Record route ping -n host # Numeric only (no DNS) # IPv6 ping6 host # IPv6 ping ping -6 host # IPv6 ping # Interface selection ping -I eth0 host # Use specific interface ping -I 192.168.1.1 host # Use specific source IP # With deadline ping -w 10 host # Stop after 10 seconds ping -c 10 -w 5 host # Stop after 5 sec or 10 packets
Common One-Liners
# Quick connectivity check
ping -c 1 8.8.8.8 >/dev/null && echo "Online" || echo "Offline"
# Monitor with timestamp
ping -D google.com | while read line; do echo "$(date): $line"; done
# Average RTT only
ping -c 10 -q google.com | grep avg | cut -d/ -f5
# Packet loss only
ping -c 10 -q google.com | grep -oP '\d+(?=% packet loss)'
# Continuous logging
ping -i 60 google.com | while read line; do echo "$(date): $line" >> ping.log; done
# Scan local network
for i in {1..254}; do ping -c 1 -W 1 192.168.1.$i >/dev/null && echo "Host 192.168.1.$i is up"; done
# Test MTU
ping -c 1 -M do -s 1472 8.8.8.8 >/dev/null && echo "MTU 1500 works"
# Monitor with visual indicator
ping -c 100 google.com | grep -o 'time=[0-9.]*' | cut -d= -f2 | awk '{if($1>100) print "⚡",$1,"ms"; else print "·",$1,"ms"}'
Exit Codes
# ping exit codes and their meanings # 0 = Success (all packets received) # 1 = Failed (some packets lost or host unreachable) # 2 = Invalid usage or options ping -c 1 example.com case $? in 0) echo "Host reachable" ;; 1) echo "Host unreachable" ;; 2) echo "Invalid command" ;; esac
Conclusion
The ping command is an essential tool for network troubleshooting and monitoring:
Key Takeaways
- Network Testing: Verify connectivity to hosts
- Performance Measurement: Measure latency and packet loss
- Troubleshooting: Identify network issues
- Monitoring: Track network stability over time
- Scripting: Integrate into automation and monitoring systems
Best Practices Summary
| Scenario | Recommended Command |
|---|---|
| Quick connectivity | ping -c 4 host |
| Continuous monitoring | ping -i 60 host |
| Quality test | ping -c 100 -q host |
| MTU discovery | ping -M do -s size host |
| Interface test | ping -I interface host |
| Script usage | ping -c 1 -W 2 host >/dev/null |
| With timestamps | ping -D host |
Safety Guidelines
- Don't flood networks without permission
- Use appropriate timeouts in scripts
- Consider ICMP filtering on some hosts
- Respect rate limiting on production networks
- Combine with other tools for comprehensive analysis
The ping command's simplicity and ubiquity make it an indispensable tool for anyone working with networks, from casual users to system administrators.