Bash 脚本来 ping 一个 IP,如果 ms 超过 100,则打印一个 echo msg

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28130330/
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-09-18 12:15:13  来源:igfitidea点击:

Bash script to ping a IP and if the ms is over 100 print a echo msg

bashshelldebianshbin

提问by Menju

Im new to bash scripting.

我是 bash 脚本的新手。

I need a script to get the ms of a ping to a IP and if the time is over 100 it will print a echo message.

我需要一个脚本来获取 ping 到 IP 的毫秒数,如果时间超过 100,它将打印一条回显消息。

For the example lets do it with the google ip 8.8.8.8

例如,让我们使用 google ip 8.8.8.8

Could you please help me?

请你帮助我好吗?

Edit:

编辑:

Okay how to make it like this:

好的,如何使它像这样:

#!/bin/sh

echo '>> Start ping test 2.0'

/bin/ping 8.8.8.8 | awk -F' |=' '=="time"'

if [>100]
    then
        echo "Slow response"
    else
        echo "Fast response"
fi

回答by ghoti

Okay... First off, you are not writing a bash script, your script is called using #!/bin/sh, so even if your system uses bash as its system shell, it's being run in sh compatibility mode. So you can't use bashisms. Write your script as I've shown below instead.

好的...首先,您不是在编写 bash 脚本,您的脚本是通过 using 调用的#!/bin/sh,因此即使您的系统使用 bash 作为其系统外壳,它也是在 sh 兼容模式下运行的。所以你不能使用bashisms。编写您的脚本,如下所示。

So... it seems to me that if you want your pingto have output that is handled by your script, then the pingneeds to actually EXIT. Your ifwill never get processed, because pingnever stops running. And besides $11within the awk script isn't the same as $11within the shell script. So something like this might work:

所以......在我看来,如果你希望你的ping输出由你的脚本处理,那么ping需要实际退出。你if永远不会得到处理,因为ping永远不会停止运行。此外$11,在 awk 脚本中与$11在 shell 脚本中不同。所以这样的事情可能会奏效:

#!/bin/bash

while sleep 5; do
  t="$(ping -c 1 8.8.8.8 | sed -ne '/.*time=/{;s///;s/\..*//;p;}')"
  if [ "$t" -gt 100 ]; then
    # do something
  else
    # do something else
  fi
done

This while loop, in shell (or bash) will run ping every five seconds with only one packet sent (the -c 1), and parse its output using sed. The sedscript works like this:

这个 while 循环,在 shell(或 bash)中将每五秒运行一次 ping,只发送一个数据包(the -c 1),并使用sed. 该sed脚本的工作方式如下:

  • /.*time=/{...}- look for a line containing the time and run stuff in the curly braces on that line...
  • s///- substitute the previously found expression (the time) with nothing (erasing it from the line)
  • s/\..*//- replace everything from the first period to the end of the line with nothing (since shell math only handles integers)
  • p- and print the remaining data from the line.
  • /.*time=/{...}- 查找包含时间的行并在该行的花括号中运行内容...
  • s///- 用空替换先前找到的表达式(时间)(从行中删除它)
  • s/\..*//- 用空替换从第一个句点到行尾的所有内容(因为 shell 数学只处理整数)
  • p- 并打印行中的剩余数据。

And alternate way of handling this is to parse ping's output as a streaminstead of spawning a new ping process for each test. For example:

处理此问题的另一种方法是将ping的输出解析为流,而不是为每个测试生成一个新的 ping 进程。例如:

#!/bin/bash

ping -i 60 8.8.8.8 | while read line; do
  case "$line" in
  *time=*ms)
    t=${line#.*=}   # strip off everything up to the last equals
    t=${t% *}       # strip off everything from the last space to the end
    if [[ (($t > 100)) ]]; then
      # do something
    else
      # do something else
    fi
    ;;
done

These solutions are a bit problematic in that they fail to report when connectivity goes away ENTIRELY. But perhaps you can adapt them to handle that case too.

这些解决方案有点问题,因为它们无法在连接完全消失时报告。但也许你也可以调整它们来处理这种情况。

Note that these may not be your best solution. If you really want a monitoring system, larger scale things like Nagios, Icinga, Munin, etc, are a good way to go.

请注意,这些可能不是您的最佳解决方案。如果你真的想要一个监控系统,像NagiosIcingaMunin等更大规模的东西是一个很好的方法。

For small-scale ping monitoring like this, you might also want to look at fping.

对于像这样的小规模 ping 监控,您可能还想查看fping

回答by thomaswsdyer

There's a couple transformations you'll need to do to the pingoutput in order to get the actual number for milliseconds.

ping为了获得毫秒的实际数字,您需要对输出进行一些转换。

First, to make this simple, use the -c 1flag for pingto only send one packet.

首先,为了简单起见,使用-c 1标志 forping仅发送一个数据包。

The output for pingwill look like:

的输出ping将如下所示:

PING 8.8.8.8 (8.8.8.8): 56 data bytes
64 bytes from 8.8.8.8: icmp_seq=0 ttl=59 time=41.101 ms

--- 8.8.8.8 ping statistics ---
1 packets transmitted, 1 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 41.101/41.101/41.101/0.000 mss

Since you want the '41.101' piece, you'll need to parse out the second to last elementof the second line.

既然你想要的'41 0.101'一块,你需要解析出倒数第二个元素的的第二线

To extract the second line you can use the FNRvariable in awk, and to get the second to last column you can use the NF(number of fields) variable.

要提取第二行,您可以使用FNR变量 in awk,并获取倒数第二列,您可以使用NF(字段数)变量。

ping -c 1 8.8.8.8 |  awk 'FNR == 2 { print $(NF-1) }'

This will give you time=41.101, to get just the number use cutto extract the field after the equals sign

这将为您提供用于提取等号后字段time=41.101的数字cut

ping -c 1 8.8.8.8 |  awk 'FNR == 2 { print $(NF-1) }' | cut -d'=' -f2

回答by Magnus Zetterberg

This is what I did to get a trace on slow ping times and also get a mail sent to me or anyone if you want to have that.

这就是我所做的,以跟踪缓慢的 ping 时间,并且如果您想要的话,还会收到发送给我或任何人的邮件。

#!/bin/bash

if [ "$#" -ne 1 ]; then
    echo "You must enter 1 command line arguments - The address which you want to ping against"
exit
fi

hostname=$(hostname)

while true; do

RESULT=$(ping -c 1  | awk -v time="$(date +"%Y-%m-%d %H:%M:%S")" -Ftime= 'NF>1{if (+0 > 1) print      " "time }')

if [ "$RESULT" != "" ]; then
echo $RESULT >> pingscript.log
echo $RESULT | mail -s "pingAlert between $hostname -  " [email protected]
fi

sleep 2
done