如何为每个ping结果加上时间戳?

102

Ping 默认会返回如下信息:

64 bytes from 203.173.50.132: icmp_seq=0 ttl=244 time=57.746 ms

有没有办法让它添加时间戳?

比如说,

Mon 21 May 2012 15:15:37 EST | 64 bytes from 203.173.50.132: icmp_seq=0 ttl=244 time=57.746 ms

我使用的操作系统是OS X v10.7(Lion),似乎自带一种基于BSD的ping命令。

16个回答

153

由于某些原因我无法将基于Perl的解决方案重定向到文件中,所以我继续搜索并找到了一个仅使用bash的方法来实现这一点:

ping www.google.fr | while read pong; do echo "$(date): $pong"; done

Wed Jun 26 13:09:23 CEST 2013: PING www.google.fr (173.194.40.56) 56(84) bytes of data.
Wed Jun 26 13:09:23 CEST 2013: 64 bytes from zrh04s05-in-f24.1e100.net (173.194.40.56): icmp_req=1 ttl=57 time=7.26 ms
Wed Jun 26 13:09:24 CEST 2013: 64 bytes from zrh04s05-in-f24.1e100.net (173.194.40.56): icmp_req=2 ttl=57 time=8.14 ms

功劳归于https://askubuntu.com/a/137246


1
这似乎在Debian Wheezy上无法工作。直到按下ctrl+c之前,输出一直停留在那里。 - KBeezie
1
@KBeezie 不确定你的情况是什么问题。我在 Debian Wheezy 上刚尝试了一下,运行良好。你是否使用 bash 作为你的 shell? - richk
8
我实际上更喜欢这种方法,因为它不使用perl或awk。 - Alexey Kamenskiy
5
要查看超时信息,只需要在管道符(|)之前将 stderr 重定向到 stdout,例如:ping $host 2>&1 | while read pong; do echo "$(date): $pong"; done。如果您希望将其写入(或追加)到文件中,可以在 done 后面将整个命令重定向。此外,如果您不想生成子shell,则 date 命令支持输出任意输入,例如:ping $host 2>&1 | while read pong; do date "+%c: $pong"; done。请注意,dateformat 参数(以 + 开头)可以随意自定义。有关更多信息,请参见 man date - 7heo.tk
以下是鱼版本:ping google.fr | while read pong; echo (date)": $pong"; end - Byscripts
显示剩余3条评论

81

如果你的 AWK 没有 strftime()

ping host | perl -nle 'print scalar(localtime), " ", $_'

要将其重定向到文件,请使用标准的shell重定向并关闭输出缓冲:

ping host | perl -nle 'BEGIN {$|++} print scalar(localtime), " ", $_' > outputfile

如果您想要时间戳使用 ISO8601 格式:

ping host | perl -nle 'use Time::Piece; BEGIN {$|++} print localtime->datetime, " ", $_' > outputfile

尽管我删除了“bytes from”过滤器,因为我想要每行的时间戳...特别是超时。 - John Mee
工作得很好,但是当你按Control+C时,它会压制摘要结果的STDERR。BASH答案存在相同的问题。 - Nicholas Blasgen
1
@NicholasBlasgen:这是因为Ctrl-C会发送到管道中的最后一个进程,而ping只接收到SIGPIPE。您可以使用进程替换代替管道:ping host > >(perl -nle 'print scalar(localtime), " ", $_'),然后Ctrl-C将转到ping并执行您想要的操作。您也可以对while循环执行相同的操作。顺便说一下,在我的系统上,摘要会发送到STDOUT而不是STDERR(因此也会被时间戳记)。 - Dennis Williamson
在我看来,如果日期时间格式采用ISO8601标准,这个答案会更好。 - Phrogz
@Phrogz:我同意这是更理想的格式,但我的答案接近于匹配OP所要求的(取决于区域设置)。要获取ISO8601格式,您可以使用Time::Piece;从5.10开始打印本地时间->datetime(和其他适当的设置)或使用CPAN模块或strftime。 - Dennis Williamson
关于楼主的格式,提出了很好的观点!感谢您包括 iso8601 的等效项。 - Phrogz

37

来自 man ping

   -D     Print timestamp (unix time + microseconds as in gettimeofday) before each line.

它将产生类似于这样的东西:

[1337577886.346622] 64 bytes from 4.2.2.2: icmp_req=1 ttl=243 time=47.1 ms

然后可以从ping响应中解析出时间戳,并使用date将其转换为所需的格式。


2
抱歉,当我添加标签时ADSL断开了连接...我的OSX Lion系统没有“-D”选项:-( - John Mee
熟练掌握 Perl 和正则表达式的人可以将其传输到格式化为可读日期时间的管道中。 =] - Cleber Reizen

31

在 OS X 上,您可以简单地使用 --apple-time 选项:

ping -i 2 --apple-time www.apple.com

生成类似以下结果:

10:09:55.691216 64 bytes from 72.246.225.209: icmp_seq=0 ttl=60 time=34.388 ms
10:09:57.687282 64 bytes from 72.246.225.209: icmp_seq=1 ttl=60 time=25.319 ms
10:09:59.729998 64 bytes from 72.246.225.209: icmp_seq=2 ttl=60 time=64.097 ms

2
这个不处理超时。 - Andrew Grimm

22
  1. 终端输出:

    ping -i 5 google.com | xargs -L 1 -I '{}' date '+%Y-%m-%d %H:%M:%S: {}'

  2. 文件输出:

    ping -i 5 google.com | xargs -L 1 -I '{}' date '+%Y-%m-%d %H:%M:%S: {}' > test.txt

  3. 终端和文件输出:

    ping -i 5 google.com | xargs -L 1 -I '{}' date '+%Y-%m-%d %H:%M:%S: {}' | tee test.txt

  4. 后台文件输出:

    nohup ping -i 5 google.com | xargs -L 1 -I '{}' date '+%Y-%m-%d %H:%M:%S: {}' > test.txt &


14

我的原始提交不正确,因为它没有对每行日期进行评估。已做出更正。

请尝试这个。

 ping google.com | xargs -L 1 -I '{}' date '+%+: {}'

产生以下输出

Thu Aug 15 10:13:59 PDT 2013: PING google.com (74.125.239.103): 56 data bytes
Thu Aug 15 10:13:59 PDT 2013: 64 bytes from 74.125.239.103: icmp_seq=0 ttl=55 time=14.983 ms
Thu Aug 15 10:14:00 PDT 2013: 64 bytes from 74.125.239.103: icmp_seq=1 ttl=55 time=17.340 ms
Thu Aug 15 10:14:01 PDT 2013: 64 bytes from 74.125.239.103: icmp_seq=2 ttl=55 time=15.898 ms
Thu Aug 15 10:14:02 PDT 2013: 64 bytes from 74.125.239.103: icmp_seq=3 ttl=55 time=15.720 ms
Thu Aug 15 10:14:03 PDT 2013: 64 bytes from 74.125.239.103: icmp_seq=4 ttl=55 time=16.899 ms
Thu Aug 15 10:14:04 PDT 2013: 64 bytes from 74.125.239.103: icmp_seq=5 ttl=55 time=16.242 ms
Thu Aug 15 10:14:05 PDT 2013: 64 bytes from 74.125.239.103: icmp_seq=6 ttl=55 time=16.574 ms

-L 1选项会导致xargs每次处理一行而非单词。


在“请求超时”期间不打印;将它们全部保存起来,当请求超时停止时,它们会被一起丢弃,并带有相同的时间戳。 - David Eison
@DavidEison 请尝试使用 ping -D -n -O -i1 -W1 8.8.8.8 命令。 - Thomas Szteliga

10
较为简单的选择是只使用moreutils中的ts(1)命令(大多数发行版都已经默认安装了该软件)。
$ ping 1.1.1.1 | ts 

Feb 13 12:49:17 PING 1.1.1.1 (1.1.1.1) 56(84) bytes of data. 
Feb 13 12:49:17 64 bytes from 1.1.1.1: icmp_seq=1 ttl=57 time=5.92 ms
Feb 13 12:49:18 64 bytes from 1.1.1.1: icmp_seq=2 ttl=57 time=5.30 ms
Feb 13 12:49:19 64 bytes from 1.1.1.1: icmp_seq=3 ttl=57 time=5.71 ms
Feb 13 12:49:20 64 bytes from 1.1.1.1: icmp_seq=4 ttl=57 time=5.86 ms

或者

 ping 1.1.1.1 -I eth0 | ts "[%FT%X]"

允许使用与shell/date解决方案相同的strftime格式字符串。


10
在macOS上,您可以执行以下操作:

ping --apple-time 127.0.0.1

输出如下:
16:07:11.315419 64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.064 ms
16:07:12.319933 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.157 ms
16:07:13.322766 64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.066 ms
16:07:14.324649 64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.148 ms
16:07:15.328743 64 bytes from 127.0.0.1: icmp_seq=4 ttl=64 time=0.092 ms

这种方法似乎对回复来说还可以,但超时的时间戳被排除在外。 - Robert Hartshorn

7

试试这个:

ping www.google.com | while read endlooop; do echo "$(date): $endlooop"; done

它会返回类似以下的内容:
Wednesday 18 January  09:29:20 AEDT 2017: PING www.google.com (216.58.199.36) 56(84) bytes of data.
Wednesday 18 January  09:29:20 AEDT 2017: 64 bytes from syd09s12-in-f36.1e100.net (216.58.199.36): icmp_seq=1 ttl=57 time=2.86 ms
Wednesday 18 January  09:29:21 AEDT 2017: 64 bytes from syd09s12-in-f36.1e100.net (216.58.199.36): icmp_seq=2 ttl=57 time=2.64 ms
Wednesday 18 January  09:29:22 AEDT 2017: 64 bytes from syd09s12-in-f36.1e100.net (216.58.199.36): icmp_seq=3 ttl=57 time=2.76 ms
Wednesday 18 January  09:29:23 AEDT 2017: 64 bytes from syd09s12-in-f36.1e100.net (216.58.199.36): icmp_seq=4 ttl=57 time=1.87 ms
Wednesday 18 January  09:29:24 AEDT 2017: 64 bytes from syd09s12-in-f36.1e100.net (216.58.199.36): icmp_seq=5 ttl=57 time=2.45 ms

4
将结果传输到awk:
 ping host | awk '{if($0 ~ /bytes from/){print strftime()"|"$0}else print}'

有前途!不喜欢strftime,所以我正在努力解决。 - John Mee
检查这段代码时,使用一个不存在的主机或者在网络不可用的情况下。对于这个结果我并不满意;-) - Thomas Szteliga

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接