You can also use gawk
(or awk
, if your /etc/alternatives/awk
points to /usr/bin/gawk
):
ping -c 4 www.google.fr | gawk '{print strftime("%c: ") $0}'
This is similar to the approach in Achu's answer, but ping
's output is piped to gawk
instead of a shell loop that calls date
. As with that approach, it works without -c
, but if you don't pass -c n
to make ping stop after n pings, and you stop the loop with Ctrl+C, ping
won't print the usual statistics.
ek@Io:~$ ping -c 4 www.google.fr | gawk '{print strftime("%c: ") $0}'
Tue 03 Jan 2017 10:09:51 AM EST: PING www.google.fr (216.58.193.99) 56(84) bytes of data.
Tue 03 Jan 2017 10:09:51 AM EST: 64 bytes from sea15s08-in-f3.1e100.net (216.58.193.99): icmp_seq=1 ttl=51 time=327 ms
Tue 03 Jan 2017 10:09:52 AM EST: 64 bytes from sea15s08-in-f3.1e100.net (216.58.193.99): icmp_seq=2 ttl=51 time=302 ms
Tue 03 Jan 2017 10:09:53 AM EST: 64 bytes from sea15s08-in-f3.1e100.net (216.58.193.99): icmp_seq=3 ttl=51 time=282 ms
Tue 03 Jan 2017 10:09:54 AM EST: 64 bytes from sea15s08-in-f3.1e100.net (216.58.193.99): icmp_seq=4 ttl=51 time=349 ms
Tue 03 Jan 2017 10:09:54 AM EST:
Tue 03 Jan 2017 10:09:54 AM EST: --- www.google.fr ping statistics ---
Tue 03 Jan 2017 10:09:54 AM EST: 4 packets transmitted, 4 received, 0% packet loss, time 3003ms
Tue 03 Jan 2017 10:09:54 AM EST: rtt min/avg/max/mdev = 282.035/315.227/349.166/25.398 ms
ek@Io:~$ ping www.google.fr | gawk '{print strftime("%c: ") $0}'
Tue 03 Jan 2017 10:10:35 AM EST: PING www.google.fr (216.58.193.99) 56(84) bytes of data.
Tue 03 Jan 2017 10:10:35 AM EST: 64 bytes from sea15s08-in-f99.1e100.net (216.58.193.99): icmp_seq=1 ttl=51 time=305 ms
Tue 03 Jan 2017 10:10:35 AM EST: 64 bytes from sea15s08-in-f99.1e100.net (216.58.193.99): icmp_seq=2 ttl=51 time=365 ms
Tue 03 Jan 2017 10:10:36 AM EST: 64 bytes from sea15s08-in-f99.1e100.net (216.58.193.99): icmp_seq=3 ttl=51 time=390 ms
Tue 03 Jan 2017 10:10:38 AM EST: 64 bytes from sea15s08-in-f99.1e100.net (216.58.193.99): icmp_seq=4 ttl=51 time=824 ms
Tue 03 Jan 2017 10:10:38 AM EST: 64 bytes from sea15s08-in-f99.1e100.net (216.58.193.99): icmp_seq=5 ttl=51 time=287 ms
^C
This happens whether ping
's output is piped to gawk
or a shell while
loop. The reason is that command on the right side of the pipe, rather than ping
, receives SIGINT when Ctrl+C is pressed, and ping
does not know to print the statistics before being terminated.
If you have run ping
without -c
on the left side of a pipe (as shown above) and you want to terminate it in such a way that it still prints the statistics, then instead of pressing Ctrl+C in the terminal where it is running, you could run kill -INT PID
from another terminal, replacing PID
with the process ID of the ping
command. If you're only running one instance of ping
then you could simply use killall -INT ping
.
Alternatively, you could replace the ping
command on the left side of the pipe with a command that runs a shell, reports the process ID of that shell, and then replaces that shell with the ping
command (causing it to have the same PID):
sh -c 'echo $$; exec ping www.google.fr' | gawk '{print strftime("%c: ") $0}'
Then the first line of output, will show the process ID of the ping
command (which will typically be different each time). It would look like this, but with a different time and date and probably a different process ID:
Tue 20 Mar 2018 12:11:13 PM EDT: 7557
Then, from another terminal, you can run kill -INT 7557
, replacing 7557
with the actual process ID you saw, to terminate the ping
command in such a way as to cause it to print statistics.
(If you take advantage of your shell's job control features, then you can achieve this within the same terminal, too. But if you want to copy text from your terminal without having to remove any extranous part where you ran commands in that terminal, then you should terminate ping
from a separate terminal.)
Further reading: