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

时间:2011-11-29 16:28:46

标签: linux bash ping

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

6 个答案:

答案 0 :(得分:8)

与往常一样,有很多不同的方法可以做到这一点。但是这里有一个选择:

此表达式将捕获“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]

答案 1 :(得分:8)

到目前为止,我们已经使用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 '...'

我们首先将google.com和piping the output ping到解释器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,并为其指定当前行号减一。

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

我们在这里使用Regular Expresssion^.*(time=.+ ms).*$来确定ICMP请求是否成功。由于每次成功的ping都会返回它所用的时间长度,因此我们将其用作关键字。

对于那些不具备正则表达式模式的人来说,这就是我们的意思:

  1. ^从行的开头
  2. 开始
  3. .*匹配任何内容,直到下一个规则
  4. (time=.+ ms)匹配“time = N ms”,其中N可以是任何字符中的一个或多个
  5. .*匹配任何内容,直到下一个规则
  6. $停在该行的末尾
  7. 当模式匹配时,我们递增received变量。

    计算损失

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

    现在我们知道发送和接收了多少ICMP请求,我们可以开始进行数学运算以确定数据包丢失。为避免divide by zero错误,我们确保在进行任何计算之前已发送请求。计算本身很简单:

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

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

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


      我不想记住所有这些

      您可以将脚本保存到文件中(例如packet_loss.awk),而不是每次都输入该内容,或者搜索此答案。然后您需要键入的是:

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

答案 2 :(得分:3)

假设你的ping结果如下:

PING host.example (192.168.0.10) 56(84) bytes of data.

--- host.example ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4000ms
rtt min/avg/max/mdev = 0.209/0.217/0.231/0.018 ms

通过管道ping -c 5 -q

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

收率:

5

然后你可以执行算术。

答案 3 :(得分:1)

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

答案 4 :(得分:0)

尝试一个脚本:

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

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

答案 5 :(得分:0)

这对你有用吗?

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

它需要ping报告的百分比,并从100减去它以获得收到的数据包的百分比。