Skip to content

Latest commit

 

History

History
123 lines (107 loc) · 6.44 KB

为ping命令增加时间信息的正确方法.org

File metadata and controls

123 lines (107 loc) · 6.44 KB

为ping命令增加时间信息的正确方法

不知道为什么,在网上搜索为 ping 命令增加时间信息方法时,给出来得解决方案都是将 ping 命令的结果传递给一个循环,然后在循环内生成时间。

这个循环可能是一个流式处理命令,比如 awk:

ping www.baidu.com -c 5 | awk '{ print strftime("%Y-%m-%d %H:%M:%S",systime())"\t"$0 }'

也可能是一个 while 循环语句:

ping www.baidu.com -c 5 |while read result
do
    echo "$(date) ${result}"
done

但是这有个问题,那就是时间戳不是由 ping 命令生成的,而是在循环体内生成的。这就导致若我们在时间戳生成之前用 sedawk 之类的命令对 ping 结果加工后,由于它们的缓存机制会使得输出到循环的时间比实际 ping 命令产生结果的时间产生较大差别。

例如下面命令的输出中,生成的时间是同一秒,这明显是不对的。

ping www.baidu.com -c 5|awk '1' | awk '{ print strftime("%Y-%m-%d %H:%M:%S",systime())"\t"$0 }'

事实上,通过查看 ping 命令的 manual, 我们可以发现 ping 命令的 -D 选项本身就会为每一行输出生成时间戳:

-D     Print timestamp (unix time + microseconds as in gettimeofday) before each line.
ping -c 5 www.baidu.com -D

唯一的问题就是这个时间戳采取的是是从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