Reputation: 237
I am trying to write a small script that will track network latency with ping.
I need to write to a file and tag each ping entry with a date and time. I need to see the responses in real time and stop the script if the ping times are too long.
I can get the ping results and summary in a file without the date, code below
#!/usr/bin/env bash
echo "Enter Dealer number: "
read deal
echo "Enter IP address: "
read ip
touch ./${deal}_pingtest.txt
ping $ip > ./${deal}_pingtest.txt &
tail -f ./${deal}_pingtest.txt
stdout results
Enter Dealer number:
test
Enter IP address:
8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=58 time=4.87 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=58 time=5.36 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=58 time=8.30 ms
64 bytes from 8.8.8.8: icmp_seq=4 ttl=58 time=4.48 ms
^C
File results
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=58 time=4.87 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=58 time=5.36 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=58 time=8.30 ms
64 bytes from 8.8.8.8: icmp_seq=4 ttl=58 time=4.48 ms
--- 8.8.8.8 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 2999ms
rtt min/avg/max/mdev = 4.488/5.758/8.309/1.506 ms
when I add the date to the script the file results never show the stats script with timestamp
#!/usr/bin/env bash
echo "Enter Dealer number: "
read deal
echo "Enter IP address: "
read ip
touch ./${deal}_pingtest.txt
ping $ip | while read pong; do echo "$(date +%Y-%m-%d\|%H:%M:%S): $pong"; done > ./${deal}_pingtest.txt &
tail -f ./${deal}_pingtest.txt
stdout results
Enter Dealer number:
test
Enter IP address:
8.8.8.8
2017-08-04|11:31:29: PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
2017-08-04|11:31:29: 64 bytes from 8.8.8.8: icmp_seq=1 ttl=58 time=4.71 ms
2017-08-04|11:31:30: 64 bytes from 8.8.8.8: icmp_seq=2 ttl=58 time=4.53 ms
2017-08-04|11:31:31: 64 bytes from 8.8.8.8: icmp_seq=3 ttl=58 time=4.85 ms
2017-08-04|11:31:32: 64 bytes from 8.8.8.8: icmp_seq=4 ttl=58 time=5.11 ms
2017-08-04|11:31:33: 64 bytes from 8.8.8.8: icmp_seq=5 ttl=58 time=4.51 ms
^C
file results
2017-08-04|11:31:29: PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
2017-08-04|11:31:29: 64 bytes from 8.8.8.8: icmp_seq=1 ttl=58 time=4.71 ms
2017-08-04|11:31:30: 64 bytes from 8.8.8.8: icmp_seq=2 ttl=58 time=4.53 ms
2017-08-04|11:31:31: 64 bytes from 8.8.8.8: icmp_seq=3 ttl=58 time=4.85 ms
2017-08-04|11:31:32: 64 bytes from 8.8.8.8: icmp_seq=4 ttl=58 time=5.11 ms
2017-08-04|11:31:33: 64 bytes from 8.8.8.8: icmp_seq=5 ttl=58 time=4.51 ms
2017-08-04|11:31:34: 64 bytes from 8.8.8.8: icmp_seq=6 ttl=58 time=4.89 ms
Thank you all for any guidance.
Upvotes: 3
Views: 908
Reputation: 2374
I assume you're using ctrl-C
at the keyboard to interrupt this script. You need to code things so that the ping
command is interrupted and emits its summary info, but the shell capturing the output of ping
survives to capture that summary and emit it to the output file.
This seems like a job for the trap
builtin to bash
.
Adjusting your original script:
#!/usr/bin/env bash
read -p "Enter Dealer number: " deal
read -p "Enter IP address: " ip
trap INT
ping $ip | while read pong; do echo "$(date +%Y-%m-%d\|%H:%M:%S): $pong"; done > "$deal"_pingtest.txt &
tail -f "$deal"_pingtest.txt
From the SIGNALS section of the man page for bash
: Non-builtin commands run by bash have signal handlers set to the values inherited by the shell from its parent.
The trap
command above means that the shell running the while loop will not respond to the keyboard interrupt (signal INT
), but the non-builtin ping
command will have its disposition reset to default when bash
launches it, so will be interrupted by the keyboard signal. ping
then emits its summary and exits, and the shell survives to capture all of that output.
You could also structure things so that you don't rely on a background process / tail
combination:
#!/usr/bin/env bash
read -p 'Enter Dealer number: ' deal
read -p 'Enter IP address: ' ip
trap '' INT
ping "$ip" |
while read pong; do
echo "$(date '+%Y-%m-%d|%H:%M:%S'): $pong"
done | tee "$deal"_pingtest.txt
Note that in both I use the read
builtin and its -p option to prompt for input.
Upvotes: 2
Reputation: 18697
ping
will show the stats only if killed with SIGINT
or SIGQUIT
(or if the number of pings defined with -c count
is reached, but you're not using that). From man ping
:
When the specified number of packets have been sent (and received) or if the program is terminated with a SIGINT, a brief summary is displayed. Shorter current statistics can be obtained without termination of process with signal SIGQUIT.
So, if you want statistics printed, be sure to kill ping
like this:
pkill ping -SIGINT
Upvotes: 2