ping简介
ping是一种计算机网络工具,用来测试数据包能否透过IP协议到达特定主机。ping的运作原理是向目标主机传出一个ICMP的请求回显数据包,并等待接收回显回应数据包。程序会按时间和成功响应的次数估算丢失数据包率(丢包率)和数据包往返时间(网络时延,Round-trip delay time)。
直接ping ip
即可。
若显示ping
的回显时间,此命令也提供了参数 -D
来回显时间戳。
rues@rues-virtual-machine:~$ ping www.baidu.com -D
PING www.a.shifen.com (14.215.177.39) 56(84) bytes of data.
[1673402731.237683] 64 bytes from 14.215.177.39: icmp_seq=1 ttl=128 time=34.0 ms
[1673402732.202997] 64 bytes from 14.215.177.39: icmp_seq=2 ttl=128 time=33.5 ms
[1673402733.204868] 64 bytes from 14.215.177.39: icmp_seq=3 ttl=128 time=33.0 ms
[1673402734.207801] 64 bytes from 14.215.177.39: icmp_seq=4 ttl=128 time=34.5 ms
[1673402735.208844] 64 bytes from 14.215.177.39: icmp_seq=5 ttl=128 time=33.3 ms
[1673402736.211071] 64 bytes from 14.215.177.39: icmp_seq=6 ttl=128 time=33.9 ms
然而,时间戳可读性较差,虽然可以利用网上的一些工具(unitxtime)来转化,但是比较麻烦,最好的方式时回显时就是可读性较好的时间格式。
ping命令的使用
常用参数
-i: 每次执行ping操作的间隔时间, 默认是1s;
-c: 执行ping操作的次数, 默认是一直执行, 除非被中断;
-s: 指定执行ping操作时发送的包的大小, 默认是56B, 添加报文头之后, 最终发送的是64B.
# 在终端 ping 某个地址, 执行10次
ping baidu.com -c 10 | awk '{ print $0"\t" strftime("%H:%M:%S",systime()) } '
64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=1 ttl=40 time=83.3 ms 10:41:23
64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=2 ttl=40 time=83.4 ms 10:41:24
64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=3 ttl=40 time=83.4 ms 10:41:25
# 日期在后面
ping baidu.com | awk '{ print $0"\t" strftime("%Y-%m-%d %H:%M:%S",systime()); fflush()}'
64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=1 ttl=40 time=83.2 ms 2021-06-09 10:42:45
64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=2 ttl=40 time=83.3 ms 2021-06-09 10:42:46
64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=3 ttl=40 time=83.3 ms 2021-06-09 10:42:47
# 日前在前面
ping baidu.com | awk '{ print strftime("%Y.%m.%d %H:%M:%S",systime())"\t" $0; fflush() }'
2021.06.09 10:43:28 64 bytes from 220.181.38.148 (220.181.38.148): icmp_seq=1 ttl=46 time=162 ms
2021.06.09 10:43:29 64 bytes from 220.181.38.148 (220.181.38.148): icmp_seq=2 ttl=46 time=177 ms
2021.06.09 10:43:30 64 bytes from 220.181.38.148 (220.181.38.148): icmp_seq=3 ttl=46 time=174 ms
ping将输出重定向到指定文件
使用fflush
注意:使用fflush(),不然文件不会有信息,因为awk也是有缓存的。
为防止脚本被中断, 可以通过 nohup 令脚本在后台执行:
# 下面未加fflush(),执行命令生成文件会等一会才会有信息打印到文件里
nohup ping baidu.com | awk '{ print strftime("%Y-%m-%d %H:%M:%S",systime())"\t" $0; fflush() }' >> long_ping.txt &
$ tail -f long_ping.txt
2021-06-09 10:45:54 64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=2 ttl=40 time=83.3 ms
2021-06-09 10:45:55 64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=3 ttl=40 time=83.3 ms
2021-06-09 10:45:56 64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=4 ttl=40 time=83.3 ms
# 要结束后台进程, 可通过下述方式查找并kill
$ ps -ef |grep ping
user00 5778 30382 0 10:45 pts/2 00:00:00 ping baidu.com
user00 7133 30382 0 10:48 pts/2 00:00:00 grep --color=auto ping
$ kill -9 5778
[1]+ Done nohup ping baidu.com | awk '{ print strftime("%Y.%m.%d %H:%M:%S",systime())"\t" $0; fflush() }' >> long_ping.txt
使用pong
- 什么是pingpong?
pingpong是一种数据缓存的手段,通过pingpong操作可以提高数据传输的效率。
- 什么时候需要pingpong?
在两个模块间交换数据时,上一级处理的结果不能马上被下一级所处理完成,这样上一级必须等待下一级处理完成才可以送新的数据,这样就会对性能产生很大的损失。
引入pingpong后我们可以不去等待下一级处理结束,而是将结果保存在pong路的缓存中,pong路的数据准备好的时刻,ping路的数据也处理完毕(下一级),然后无需等待直接处理pong路数据,上一级也无需等待,转而将结果存储在ping路。这样便提高了处理效率。
nohup ping baidu.com -i 1 | while read pong; do echo "$(date +"%Y-%m-%d %H:%M:%S") | $pong"; done | tee -a ping-baidu.com.log &
date时间戳
数据戳转化
date可以将时间戳转化为localtime。
# date -d @1623205723.324359
Wed Jun 9 10:28:43 CST 2021
# date --date=@1623205723.324359
Wed Jun 9 10:28:43 CST 2021
利用awk进行转化,比较麻烦。
awk拼接
# 格式可以自定义调整
ping baidu.com | awk '{"date" | getline date; print date,$0}'
Wed Jun 9 10:33:01 CST 2021 64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=2 ttl=40 time=83.3 ms
Wed Jun 9 10:33:01 CST 2021 64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=3 ttl=40 time=83.5 ms
Wed Jun 9 10:33:01 CST 2021 64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=4 ttl=40 time=83.3 ms
# 时间格式可根据date自定义
ping baidu.com | awk -v date="$(date +"%Y-%m-%d %r")" '{print date, $0}'
2021-06-09 10:33:38 AM 64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=1 ttl=40 time=83.3 ms
2021-06-09 10:33:38 AM 64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=2 ttl=40 time=83.5 ms
2021-06-09 10:33:38 AM 64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=3 ttl=40 time=83.6 ms
perl
如果 awk 没有 strftime()
Notice:报错“Can’t locate Time/Piece.pm in @INC”,需要执行命令yum -y install perl-Time-Piece
来进行必要包的安装。
# 要将其重定向到文件,请使用标准shell重定向并关闭输出缓冲:
ping baidu.com | perl -nle 'print scalar(localtime), " ", $_'
Wed Jun 9 10:36:14 2021 64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=2 ttl=40 time=83.4 ms
Wed Jun 9 10:36:15 2021 64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=3 ttl=40 time=83.5 ms
Wed Jun 9 10:36:16 2021 64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=4 ttl=40 time=83.3 ms
# 如果显示ISO8601时间格式
ping baidu.com | perl -nle 'BEGIN {$|++} print scalar(localtime), " ", $_'
Wed Jun 9 10:36:41 2021 64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=1 ttl=40 time=83.3 ms
Wed Jun 9 10:36:42 2021 64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=2 ttl=40 time=83.3 ms
Wed Jun 9 10:36:43 2021 64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=3 ttl=40 time=83.5 ms
ping baidu.com | perl -nle 'use Time::Piece; BEGIN {$|++} print localtime->datetime, " ", $_'
2021-06-09T10:37:08 64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=1 ttl=40 time=83.4 ms
2021-06-09T10:37:09 64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=2 ttl=40 time=83.4 ms
2021-06-09T10:37:10 64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=3 ttl=40 time=83.2 ms
补充
strftime补充:
函数strftime()的操作有些类似于sprintf():识别以百分号(%)开始的格式命令集合,格式化输出结果放在一个字符串中。格式化命令说明串strDest中各种日期和时间信息的确切表示方法。格式串中的其他字符原样放进串中。格式命令列在下面,它们是区分大小写的。
%a 星期几的简写
%A 星期几的全称
%b 月份的简写
%B 月份的全称
%c 标准的日期的时间串
%C 年份的前两位数字
%d 十进制表示的每月的第几天
%D 月/天/年
%e 在两字符域中,十进制表示的每月的第几天
%F 年-月-日
%g 年份的后两位数字,使用基于周的年
%G 年份,使用基于周的年
%h 简写的月份名
%H 24小时制的小时
%I 12小时制的小时
%j 十进制表示的每年的第几天
%m 十进制表示的月份
%M 十时制表示的分钟数
%n 新行符
%p 本地的AM或PM的等价显示
%r 12小时的时间
%R 显示小时和分钟:hh:mm
%S 十进制的秒数