为ping命令增加时间信息的正确方法
不知道为什么,在网上搜索为 ping 命令增加时间信息方法时,给出来得解决方案都是将 ping 命令的结果传递给一个循环,然后在循环内生成时间。
这个循环可能是一个流式处理命令,比如 awk:
ping www.baidu.com -c 5 | awk '{ print strftime("%Y-%m-%d %H:%M:%S",systime())"\t"$0 }'
2021-04-26 11:26:24 PING www.a.shifen.com (14.215.177.38) 56(84) bytes of data. 2021-04-26 11:26:24 64 bytes from 14.215.177.38 (14.215.177.38): icmp_seq=1 ttl=52 time=12.1 ms 2021-04-26 11:26:24 64 bytes from 14.215.177.38 (14.215.177.38): icmp_seq=2 ttl=52 time=9.51 ms 2021-04-26 11:26:25 64 bytes from 14.215.177.38 (14.215.177.38): icmp_seq=3 ttl=52 time=18.4 ms 2021-04-26 11:26:26 64 bytes from 14.215.177.38 (14.215.177.38): icmp_seq=4 ttl=52 time=15.4 ms 2021-04-26 11:26:27 64 bytes from 14.215.177.38 (14.215.177.38): icmp_seq=5 ttl=52 time=9.81 ms 2021-04-26 11:26:27 2021-04-26 11:26:27 --- www.a.shifen.com ping statistics --- 2021-04-26 11:26:27 5 packets transmitted, 5 received, 0% packet loss, time 10077ms 2021-04-26 11:26:27 rtt min/avg/max/mdev = 9.519/13.089/18.481/3.432 ms
也可能是一个 while 循环语句:
ping www.baidu.com -c 5 |while read result do echo "$(date) ${result}" done
2021年 04月 26日 星期一 11:25:09 CST PING www.a.shifen.com (14.215.177.38) 56(84) bytes of data. 2021年 04月 26日 星期一 11:25:09 CST 64 bytes from 14.215.177.38 (14.215.177.38): icmp_seq=1 ttl=52 time=8.73 ms 2021年 04月 26日 星期一 11:25:09 CST 64 bytes from 14.215.177.38 (14.215.177.38): icmp_seq=2 ttl=52 time=16.4 ms 2021年 04月 26日 星期一 11:25:10 CST 64 bytes from 14.215.177.38 (14.215.177.38): icmp_seq=3 ttl=52 time=9.98 ms 2021年 04月 26日 星期一 11:25:11 CST 64 bytes from 14.215.177.38 (14.215.177.38): icmp_seq=4 ttl=52 time=10.8 ms 2021年 04月 26日 星期一 11:25:12 CST 64 bytes from 14.215.177.38 (14.215.177.38): icmp_seq=5 ttl=52 time=17.3 ms 2021年 04月 26日 星期一 11:25:12 CST 2021年 04月 26日 星期一 11:25:12 CST --- www.a.shifen.com ping statistics --- 2021年 04月 26日 星期一 11:25:12 CST 5 packets transmitted, 5 received, 0% packet loss, time 7043ms 2021年 04月 26日 星期一 11:25:12 CST rtt min/avg/max/mdev = 8.731/12.684/17.392/3.548 ms
但是这有个问题,那就是时间戳不是由 ping
命令生成的,而是在循环体内生成的。这就导致若我们在时间戳生成之前用 sed
和 awk
之类的命令对 ping
结果加工后,由于它们的缓存机制会使得输出到循环的时间比实际 ping 命令产生结果的时间产生较大差别。
例如下面命令的输出中,生成的时间是同一秒,这明显是不对的。
ping www.baidu.com -c 5|awk '1' | awk '{ print strftime("%Y-%m-%d %H:%M:%S",systime())"\t"$0 }'
2021-04-26 11:27:01 PING www.a.shifen.com (14.215.177.39) 56(84) bytes of data. 2021-04-26 11:27:01 64 bytes from 14.215.177.39 (14.215.177.39): icmp_seq=1 ttl=52 time=13.2 ms 2021-04-26 11:27:01 64 bytes from 14.215.177.39 (14.215.177.39): icmp_seq=2 ttl=52 time=8.32 ms 2021-04-26 11:27:01 64 bytes from 14.215.177.39 (14.215.177.39): icmp_seq=3 ttl=52 time=18.1 ms 2021-04-26 11:27:01 64 bytes from 14.215.177.39 (14.215.177.39): icmp_seq=4 ttl=52 time=8.61 ms 2021-04-26 11:27:01 64 bytes from 14.215.177.39 (14.215.177.39): icmp_seq=5 ttl=52 time=9.09 ms 2021-04-26 11:27:01 2021-04-26 11:27:01 --- www.a.shifen.com ping statistics --- 2021-04-26 11:27:01 5 packets transmitted, 5 received, 0% packet loss, time 4052ms 2021-04-26 11:27:01 rtt min/avg/max/mdev = 8.322/11.492/18.191/3.794 ms
事实上,通过查看 ping
命令的 manual, 我们可以发现 ping 命令的 -D
选项本身就会为每一行输出生成时间戳:
-D Print timestamp (unix time + microseconds as in gettimeofday) before each line.
ping -c 5 www.baidu.com -D
PING www.a.shifen.com (14.215.177.39) 56(84) bytes of data. [1619407749.478198] 64 bytes from 14.215.177.39 (14.215.177.39): icmp_seq=1 ttl=52 time=8.86 ms [1619407749.492436] 64 bytes from 14.215.177.39 (14.215.177.39): icmp_seq=2 ttl=52 time=13.8 ms [1619407750.493666] 64 bytes from 14.215.177.39 (14.215.177.39): icmp_seq=3 ttl=52 time=13.4 ms [1619407751.492797] 64 bytes from 14.215.177.39 (14.215.177.39): icmp_seq=4 ttl=52 time=10.5 ms [1619407752.501662] 64 bytes from 14.215.177.39 (14.215.177.39): icmp_seq=5 ttl=52 time=17.1 ms --- www.a.shifen.com ping statistics --- 5 packets transmitted, 5 received, 0% packet loss, time 4042ms rtt min/avg/max/mdev = 8.861/12.776/17.120/2.861 ms
唯一的问题就是这个时间戳采取的是是从1970年1月1日(UTC/GMT的午夜)开始所经过的秒数,不方便理解,但是没关系,我们可以用 date
进行一下转换:
ping -c 5 www.baidu.com -D |awk '1' |while read result do if [[ "${result}" =~ "[" ]] # 以 [ 开头的行带时间戳 then read timestamp rest < <(echo ${result}|tr -d '[]') echo $(date -d @${timestamp}) "${rest}" else echo "${result}" fi done
PING www.a.shifen.com (14.215.177.39) 56(84) bytes of data. 2021年 04月 26日 星期一 11:41:25 CST 64 bytes from 14.215.177.39 (14.215.177.39): icmp_seq=1 ttl=52 time=8.97 ms 2021年 04月 26日 星期一 11:41:25 CST 64 bytes from 14.215.177.39 (14.215.177.39): icmp_seq=2 ttl=52 time=7.89 ms 2021年 04月 26日 星期一 11:41:26 CST 64 bytes from 14.215.177.39 (14.215.177.39): icmp_seq=3 ttl=52 time=27.3 ms 2021年 04月 26日 星期一 11:41:27 CST 64 bytes from 14.215.177.39 (14.215.177.39): icmp_seq=4 ttl=52 time=20.6 ms 2021年 04月 26日 星期一 11:41:28 CST 64 bytes from 14.215.177.39 (14.215.177.39): icmp_seq=5 ttl=52 time=22.2 ms --- www.a.shifen.com ping statistics --- 5 packets transmitted, 5 received, 0% packet loss, time 4069ms rtt min/avg/max/mdev = 7.897/17.425/27.343/7.671 ms