如何获得在bash中从Ping收到的数据包的百分比?

ping主机时,我希望我的输出只显示接收的数据包(发送5个)的百分比。 我假设我需要用某种方法使用grep但我无法弄清楚(我是bash编程的新手)。 这里是我的地方: ping -c 5 -q $host | grep ? ping -c 5 -q $host | grep ? 。 什么应该去grep? 我想我必须做一些算术来获得收到的百分比,但我可以处理。 如何从ping将输出的摘要中提取需要的信息?

Solutions Collecting From Web of "如何获得在bash中从Ping收到的数据包的百分比?"

像往常一样,有很多不同的方法来做到这一点,但这里有一个选择:

该表达式将捕获来自“X%包丢失”的百分比数字

 ping -c 5 -q $host | grep -oP '\d+(?=% packet loss)' 

然后,您可以从100中减去“损失”百分比以获得“成功”百分比:

 packet_loss=$(ping -c 5 -q $host | grep -oP '\d+(?=% packet loss)') echo $[100 - $packet_loss] 

到目前为止,我们已经有了一个使用grep,sed,perl,bc和bash的答案。 这里有一个AWK的风格,“一个解释性的编程语言设计的文本处理”。 这种方法被设计用于使用ping来查看/捕获实时分组丢失信息。

看到丢包信息:

命令

 $ ping google.com | awk '{ sent=NR-1; received+=/^.*(time=.+ ms).*$/; loss=0; } { if (sent>0) loss=100-((received/sent)*100) } { printf "sent:%d received:%d loss:%d%%\n", sent, received, loss }' 

产量

 sent:0 received:0 loss:0% sent:1 received:1 loss:0% sent:2 received:2 loss:0% sent:3 received:2 loss:33% sent:4 received:2 loss:50% sent:5 received:3 loss:40% ^C 

但是,我发现查看原始输入也很有用。 为此,您只需添加print $0; 到脚本中的最后一个块:

命令

 $ ping google.com | awk '{ sent=NR-1; received+=/^.*(time=.+ ms).*$/; loss=0; } { if (sent>0) loss=100-((received/sent)*100) } { print $0; printf "sent:%d received:%d loss:%d%%\n", sent, received, loss; }' 

产量

 PING google.com (173.194.33.104): 56 data bytes sent:0 received:0 loss:0% 64 bytes from 173.194.33.46: icmp_seq=0 ttl=55 time=18.314 ms sent:1 received:1 loss:0% 64 bytes from 173.194.33.46: icmp_seq=1 ttl=55 time=31.477 ms sent:2 received:2 loss:0% Request timeout for icmp_seq 2 sent:3 received:2 loss:33% Request timeout for icmp_seq 3 sent:4 received:2 loss:50% 64 bytes from 173.194.33.46: icmp_seq=4 ttl=55 time=20.397 ms sent:5 received:3 loss:40% ^C 

这一切是如何工作的?

你读了命令,试了一下,它的工作原理! 那么究竟发生了什么?

 $ ping google.com | awk '...' 

我们先pinging google.com,然后将输出 awk给解释器awk 。 单引号中的所有内容都定义了我们脚本的逻辑。

这是一个空格友好的格式:

 # Gather Data { sent=NR-1; received+=/^.*(time=.+ ms).*$/; loss=0; } # Calculate Loss { if (sent>0) loss=100-((received/sent)*100) } # Output { print $0; # remove this line if you don't want the original input displayed printf "sent:%d received:%d loss:%d%%\n", sent, received, loss; } 

我们可以把它分解成三个部分:

 { gather data } { calculate loss } { output } 

每次ping输出信息,AWK脚本都会消耗它并运行这个逻辑。

收集资料

 { sent=NR-1; received+=/^.*(time=.+ ms).*$/; loss=0; } 

这个有三个动作。 定义sentreceivedloss变量。

 sent=NR-1; 

NR是当前记录数量的AWK变量。 在AWK中,一条记录对应一条线。 在我们的例子中,来自ping的单行输出。 ping输出的第一行是一个头,不代表实际的ICMP请求。 所以我们创建一个变量, sent ,并为其分配当前行号减1。

 received+=/^.*(time=.+ ms).*$/; 

这里我们使用Regular Expresssion , ^.*(time=.+ ms).*$来确定ICMP请求是否成功。 由于每一次成功的ping都会返回所花费的时间,所以我们使用它作为我们的关键。

对于那些与正则表达式不太好的人来说,这就是我们的意思:

  1. ^从行首开始
  2. .*匹配任何东西,直到下一个规则
  3. (time=.+ ms)匹配“时间= N ms”,其中N可以是任何字符中的一个或多个
  4. .*匹配任何东西,直到下一个规则
  5. $在行尾停止

当模式匹配时,我们增加received变量。

计算损失

 { if (sent>0) loss=100-((received/sent)*100) } 

现在我们知道发送和接收了多少个ICMP请求,我们可以开始进行数学计算来确定数据包丢失。 为了避免被零除错误,我们确保在进行任何计算之前发送了一个请求。 计算本身非常简单:

  1. received/sent =以十进制格式成功的百分比
  2. *100 =从十进制转换为整数格式
  3. 100- =反转成功到失败的百分比

产量

 { print $0; printf "sent:%d received:%d loss:%d%%\n", sent, received, loss; } 

最后我们只需要打印相关信息。


我不想记住所有这一切

而不是每次输入,或者追查这个答案,你可以保存脚本到一个文件(例如packet_loss.awk )。 然后你需要键入的是:

 $ ping google.com | awk -f packet_loss.awk 

假设您的ping结果如下所示:

  PING host.example(192.168.0.10)56(84)字节的数据。

 --- host.example ping statistics ---
发送5个数据包,接收5个,丢包0%,时间4000ms
 rtt min / avg / max / mdev = 0.209 / 0.217 / 0.231 / 0.018ms

通过以下方式管理您的ping -c 5 -q

 grep -E -o '[0-9]+ received' | cut -f1 -d' ' 

产量:

然后你可以执行你的算术。

 echo $((100-$(ping -c 5 -q www.google.hu | sed -rn "/packet loss/ s@.*([0-9]+)%.*@\1@p"))) 

尝试一个脚本:

 /bin/bash rec=ping -c $1 -q $2 | grep -c "$2" | sed -r 's_$_ / \$1_' | xargs expr 

保存它,并用两个命令行参数运行它。 第一个是数据包的数量,第二个是主机。

这对你有用吗?

 bc -l <<<100-$(ping -c 5 -q $host | grep -o '[0-9]% packet loss' | cut -f1 -d% ) 

它使用ping报告的百分比并从100中减去以获得接收到的数据包的百分比。