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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8314219/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 02:37:32  来源:igfitidea点击:

How to get the percent of packets received from Ping in bash?

linuxbashping

提问by austinminn

When pinging a host I want my output just to show the percentage of packets (5 sent) received. I assume I need to use grepsomehow but I can't figure out how (I'm new to bash programming). Here is where I am: ping -c 5 -q $host | grep ?. What should go in grep? I think I will have to do some arithmetic to get the percent received but I can deal with that. How can I pull out the info I need from the summary that ping will output?

ping 主机时,我希望我的输出仅显示收到的数据包(发送 5 个)的百分比。我假设我需要以grep某种方式使用,但我不知道如何使用(我是 bash 编程的新手)。这是我所在的地方:ping -c 5 -q $host | grep ?。grep 应该做什么?我想我将不得不做一些算术来获得收到的百分比,但我可以解决这个问题。如何从 ping 将输出的摘要中提取我需要的信息?

采纳答案by Martin

As always, there are many different ways to do this., but here's one option:

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

This expression will capture the percent digits from "X% packet loss"

此表达式将从“X% 数据包丢失”中捕获百分比数字

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

You can then subtract the "loss" percentage from 100 to get the "success" percentage:

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

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

回答by MattH

Assuming your ping results look like:

假设您的 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

Piping your ping -c 5 -qthrough:

管道你ping -c 5 -q通过:

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

Yields:

产量:

5

And then you can perform your arithmetic.

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

回答by Spencer Rathbun

Try a script:

尝试一个脚本:

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

Save it, and run it with two command line args. The first is number of packets, the second is the host.

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

回答by choroba

Does this work for you?

这对你有用吗?

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

It takes the percentage reported by pingand subtracts it from 100 to get the percentage of received packets.

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

回答by uzsolt

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

回答by Exide

So far we've got an answer using grep, sed, perl, bc, and bash. Here is one in the flavor of AWK, "an interpreted programming language designed for text processing". This approach is designed for watching/capturing real-time packet loss information using ping.

到目前为止,我们已经使用 grep、sed、perl、bc 和 bash 得到了答案。这是AWK的风格,“一种为文本处理设计的解释型编程语言”。这种方法旨在使用ping观察/捕获实时数据包丢失信息。

To see onlypacket loss information:

查看丢包信息:

Command

命令

$ 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 }'

Output

输出

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

However, I find it useful to see the original input as well. For this you just add print $0;to the last block in the script:

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

Command

命令

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

Output

输出

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


How does this all work?

这一切是如何运作的?

You read the command, tried it, and it works! So what exactly is happening?

您阅读了命令,尝试了它,并且它有效!那么究竟发生了什么?

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

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

# Output
{
  print 
{ gather data } { calculate loss } { output }
; # remove this line if you don't want the original input displayed printf "sent:%d received:%d loss:%d%%\n", sent, received, loss; }

We start by pinging google.com and piping the outputinto awk, the interpreter. Everything in single quotes defines the logic of our script.

我们首先 ping google.com 并将输出通过管道传输到awk解释器中。单引号中的所有内容都定义了我们脚本的逻辑。

Here it is in a whitespace friendly format:

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

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

We can break it down into three components:

我们可以将其分解为三个组成部分:

sent=NR-1;

Each time ping outputs information, the AWK script will consume it and run this logic against it.

每次 ping 输出信息时,AWK 脚本都会使用它并针对它运行此逻辑。

Gather Data

收集资料

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

This one has three actions; defining the sent, received, and lossvariables.

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

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

NRis an AWK variable for the current number of records. In AWK, a record corresponds to a line. In our case, a single line of output from ping. The first line of output from ping is a header and doesn't represent an actual ICMP request. So we create a variable, sent, and assign it the current line number minus one.

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

{ print 
$ ping google.com | awk -f packet_loss.awk
; printf "sent:%d received:%d loss:%d%%\n", sent, received, loss; }

Here we use a Regular Expresssion, ^.*(time=.+ ms).*$, to determine if the ICMP request was successful or not. Since every successful ping returns the length of time it took, we use that as our key.

这里我们使用正则表达式,^.*(time=.+ ms).*$来确定 ICMP 请求是否成功。由于每次成功的 ping 都会返回花费的时间长度,因此我们将其用作密钥。

For those that aren't great with regex patterns, this is what ours means:

对于那些不擅长正则表达式模式的人,这就是我们的意思:

  1. ^starting at the beginning of the line
  2. .*match anything until the next rule
  3. (time=.+ ms)match "time=N ms", where N can be one or more of any character
  4. .*match anything until the next rule
  5. $stop at the end of the line
  1. ^从行首开始
  2. .*匹配任何东西直到下一条规则
  3. (time=.+ ms)匹配 "time=N ms",其中 N 可以是任何字符中的一个或多个
  4. .*匹配任何东西直到下一条规则
  5. $停在行尾

When the pattern is matched, we increment the receivedvariable.

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

Calculate Loss

计算损失

##代码##

Now that we know how many ICMP requests were sent and received we can start doing the math to determine packet loss. To avoid a divide by zeroerror, we make sure a request has been sent before doing any calculations. The calculation itself is pretty simple:

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

  1. received/sent= percentage of success in decimal format
  2. *100= convert from decimal to integer format
  3. 100-= invert the percentage from success to failure
  1. received/sent= 十进制格式的成功百分比
  2. *100= 从十进制转换为整数格式
  3. 100-= 反转成功与失败的百分比

Output

输出

##代码##

Finally we just need to print the relevant info.

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



I don't want to remember all of this

我不想记住这一切

Instead of typing that out every time, or hunting down this answer, you can save the script to a file (e.g. packet_loss.awk). Then all you need to type is:

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

##代码##