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

Posted

技术标签:

【中文标题】如何为每个 ping 结果添加时间戳?【英文标题】:How do I timestamp every ping result? 【发布时间】:2012-05-27 15:10:24 【问题描述】:

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。

【问题讨论】:

【参考方案1】:

由于某种原因,我无法将基于 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

【讨论】:

这似乎不适用于 debian wheezy。一直呆在那里,直到 ctrl+c @KBeezie 不确定您的情况是什么问题。我刚刚在 debian wheezy 上尝试过,效果很好。您是否使用bash 作为您的外壳? 我实际上更喜欢这种方法,因为它不使用 perl 或 awk。 要查看超时,只需在管道 (|) 之前将 stderr 重定向到 stdout,如下所示:ping $host 2>&1 | while read pong; do echo "$(date): $pong"; done。如果您希望将其写入(或附加)到文件中,您可以重定向整个命令(完成后)。此外,如果您不想生成子shell,date 命令支持echoing 任意输入,例如:ping $host 2>&1 | while read pong; do date "+%c: $pong"; done。请注意date(以+开头)的format参数可以随意自定义。请参阅man date 了解更多信息。 FWIW,我的默认 shell 是 ZSH,但它不工作。当我在 Bash 中运行它时,它运行良好。 OP 在他的评论的第一段中确实提到了这一点...... :)【参考方案2】:

如果您的 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”过滤器,因为我想要每一行的时间戳……尤其是超时。 效果很好,但是当您按 Control+C 时,它会在最后抑制汇总结果的 STDERR。 BASH 答案也存在同样的问题。 @NicholasBlasgen:这是因为 Ctrl-C 转到管道中的最后一个进程,而 ping 只收到 SIGPIPE。您可以使用进程替换而不是管道:ping host > >(perl -nle 'print scalar(localtime), " ", $_') 并且 Ctrl-C 将转到 ping 并执行您想要的操作。你可以用while 循环做同样的事情。顺便说一句,在我的系统上,摘要转到 STDOUT 而不是 STDERR(所以它也有时间戳)。 如果日期时间格式为 ISO8601,恕我直言,这个答案会更好。 @Phrogz:我同意这是一种更理想的格式,但我的回答接近于匹配 OP 的要求(取决于语言环境)。要获得 ISO8601 格式,您可以从 5.10 开始 use Time::Piece; print localtime->datetime(和其他适当的设置)或使用 CPAN 模块或 strftime【参考方案3】:

来自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 转换为所需的格式。

【讨论】:

对不起。当我添加标签时,adsl 退出了……它是 OSX Lion - 没有“-D”选项:-( 擅长 perl 和正则表达式的人可以通过管道将其格式化为人类可读的日期时间 =]【参考方案4】:

在 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

【讨论】:

这不处理超时。【参考方案5】:

    终端输出:

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

    文件输出:

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

    终端+文件输出:

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

    文件输出背景:

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

【讨论】:

【参考方案6】:

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

试试这个

 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 一次处理一行而不是单词。

【讨论】:

在“请求超时”期间不打印;将它们全部保存起来,并在请求超时停止时以相同的时间戳转储。 @DavidEison 试试ping -D -n -O -i1 -W1 8.8.8.8【参考方案7】:

在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

【讨论】:

【参考方案8】:

试试这个:

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

【讨论】:

【参考方案9】:

更简单的选择是使用 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】:

将结果传送到awk:

 ping host | awk 'if($0 ~ /bytes from/)print strftime()"|"$0else print'

【讨论】:

有承诺!不喜欢 strftime 所以我正在努力 使用不存在的主机或网络中断时检查此代码,我对此结果不满意 ;-)【参考方案11】:

你可以在你的~/.bashrc文件中创建一个函数,这样你就可以在你的控制台上得到一个ping命令ping-t

function ping-t  ping "$1" | while read pong; do echo "$(date): $pong"; done; 

现在您可以在控制台上调用它了:

ping-t example.com

Sa 31. Mär 12:58:31 CEST 2018:PING example.com (93.184.216.34) 56(84) 字节的数据。 Sa 31. Mär 12:58:31 CEST 2018:来自 93.184.216.34 (93.184.216.34) 的 64 个字节:icmp_seq=1 ttl=48 time=208 ms Sa 31. Mär 12:58:32 CEST 2018:来自 93.184.216.34 (93.184.216.34) 的 64 个字节:icmp_seq=2 ttl=48 time=233 ms

【讨论】:

【参考方案12】:

您没有指定需要此类输出多长时间的任何时间戳或间隔,因此我认为它是一个无限循环。您可以根据需要进行相应更改。

while true
do
   echo -e "`date`|`ping -n -c 1 <IP_TO_PING>|grep 'bytes from'`"
   sleep 2
done

【讨论】:

您应该将grep 部分更改为`egrep '(bytes from|errors)' @rubo77 你能详细说明为什么使用'egrep'而不是'grep' egrep 只是为了添加一个正则表达式来获取错误的输出【参考方案13】:
ping -D -n -O -i1 -W1 8.8.8.8

或许

while true; do \
    ping -n -w1 -W1 -c1 8.8.8.8 \
    | grep -E "rtt|100%" \
    | sed -e "s/^/`date` /g"; \
    sleep 1; \
done

【讨论】:

【参考方案14】:

我还需要这个来监控我的数据库镜像超时问题的网络问题。我使用的命令代码如下:

ping -t Google.com|cmd /q /v /c "(pause&pause)>nul & for /l %a in () do (set /p "data=" && echo(!date! !time! !data!)&ping -n 2 Google.com>nul" >C:\pingtest.txt

您只需将 Google.com 修改为您的服务器名称。它非常适合我。并记住在完成后停止此操作。 pingtest.txt 文件将以每秒 1 KB 的速度增加(大约)。

感谢 raymond.cc。 https://www.raymond.cc/blog/timestamp-ping-with-hrping/

【讨论】:

更新:pingtest.txt 文件将每分钟增加 4.5 KB(左右)。【参考方案15】:

试试这条线。

while sleep 1;do echo "$(date +%d-%m-%y-%T) $(ping -c 1 whatever.com | gawk 'FNR==2print "Response from:",$4,$8')" | tee -a /yourfolder/pingtest.log;done

您必须使用ctrl-c tho 取消它。

【讨论】:

使用tee 是个好主意,但-c 1 的问题是失去整体统计数据...【参考方案16】:

只需使用 sed:

ping google.com|sed -r "s/(.*)/$(date) \1/g"

【讨论】:

以上是关于如何为每个 ping 结果添加时间戳?的主要内容,如果未能解决你的问题,请参考以下文章

如何为每个键值选择具有最新时间戳的行?

sql 如何为时间戳添加时间

您如何为代码签名的 Dotnet 程序集添加时间戳?

如何为DOS批处理ping指令加时间戳?

为ping添加时间戳后台运行实时输出保存日志

如何为计时时间戳使用自定义 serde 反序列化器?