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
Bash script to ping a IP and if the ms is over 100 print a echo msg
提问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 ping
to have output that is handled by your script, then the ping
needs to actually EXIT. Your if
will never get processed, because ping
never stops running. And besides $11
within the awk script isn't the same as $11
within 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 sed
script 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.
请注意,这些可能不是您的最佳解决方案。如果你真的想要一个监控系统,像Nagios、Icinga、Munin等更大规模的东西是一个很好的方法。
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 ping
output in order to get the actual number for milliseconds.
ping
为了获得毫秒的实际数字,您需要对输出进行一些转换。
First, to make this simple, use the -c 1
flag for ping
to only send one packet.
首先,为了简单起见,使用-c 1
标志 forping
仅发送一个数据包。
The output for ping
will 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 FNR
variable 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 cut
to 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