Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 如何在bash中获取从Ping接收的数据包的百分比?_Linux_Bash_Ping - Fatal编程技术网

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

Linux 如何在bash中获取从Ping接收的数据包的百分比?,linux,bash,ping,Linux,Bash,Ping,ping主机时,我希望我的输出仅显示接收到的数据包(5个已发送)的百分比。我假设我需要以某种方式使用grep,但我不知道如何使用(我是bash编程新手)。我就在这里:ping-c5-q$host | grep?。grep中应该包含什么?我想我必须做一些算术来得到收到的百分比,但我可以处理这个问题。如何从ping将输出的摘要中提取所需的信息?假设您的ping结果如下: PING host.example (192.168.0.10) 56(84) bytes of data. --- host.

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

假设您的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 收益率:

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

一如既往,有很多不同的方法可以做到这一点,但这里有一个选项:

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

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

packet_loss=$(ping -c 5 -q $host | grep -oP '\d+(?=% packet loss)')
echo $[100 - $packet_loss]
尝试一个脚本:

/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% )

到目前为止,我们已经用grep、sed、perl、bc和bash得到了答案。这里有一个类似于“为文本处理而设计的解释性编程语言”。该方法设计用于使用监视/捕获实时丢包信息

要仅查看数据包丢失信息,请执行以下操作:

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

命令 输出
这一切是如何运作的? 你读了命令,试了试,结果成功了!那么到底发生了什么

$ ping google.com | awk '...'
我们从ping google.com开始,进入解释器
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;
NR
是当前记录数的AWK变量。在AWK中,一条记录对应一行。在我们的例子中,ping的一行输出。ping输出的第一行是一个标头,并不代表实际的ICMP请求。因此,我们创建一个变量,
sent
,并将当前行号减去一

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

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

  • ^
    从行首开始
  • *
    在下一个规则之前匹配任何内容
  • (time=.+ms)
    匹配“time=N ms”,其中N可以是任意字符中的一个或多个
  • *
    在下一个规则之前匹配任何内容
  • $
    停在该行末尾
  • 当模式匹配时,我们增加
    接收的
    变量

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

  • 接收/发送
    =十进制格式的成功百分比
  • *100
    =从十进制格式转换为整数格式
  • 100-
    =将成功与失败的百分比倒置
  • 输出 最后,我们只需要打印相关信息


    我不想记住所有这些 您可以将脚本保存到一个文件中(例如,
    packet\u loss.awk
    ),而不是每次都键入该脚本或查找该答案。那么您只需键入以下内容:

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

    我想问题是如何同时提取这两个数字。@RomanB:发送的数据包数是在ping命令行中指定的。无法使其正常工作。第一行应该是shebang?
    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 '...'
    
    # 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 }
    
    { sent=NR-1; received+=/^.*(time=.+ ms).*$/; loss=0; }
    
    sent=NR-1;
    
    received+=/^.*(time=.+ ms).*$/;
    
    { if (sent>0) loss=100-((received/sent)*100) }
    
    { print $0; printf "sent:%d received:%d loss:%d%%\n", sent, received, loss; }
    
    $ ping google.com | awk -f packet_loss.awk