在bash脚本中使用ping检查主机可用性

bur*_*tek 65 bash networking ping connectivity

我想编写一个脚本,该脚本将继续检查网络中的任何设备是否应该全天在线.我试过用ping,但是

if [ "`ping -c 1 some_ip_here`" ]
then
  echo 1
else
  echo 0
fi
Run Code Online (Sandbox Code Playgroud)

给人1如果我输入有效或无效的IP地址不管.如何检查特定地址(或更好的IP地址列表中的任何设备)是否脱机?

Sti*_*anE 63

Ping根据错误类型返回不同的退出代码.

ping 256.256.256.256 ; echo $?
# 68

ping -c 1 127.0.0.1 ; echo $?
# 0

ping -c 1 192.168.1.5 ; echo $?
# 2
Run Code Online (Sandbox Code Playgroud)

0表示主机可达

2意味着无法到达

  • 你第一次得到'68`吗?我得到'2`并且未知主持人.在第三个示例中,我得到了`1`,目标主机无法访问. (3认同)
  • 确实如此,你的if会在任何非0退出代码上触发`echo 1`块(所有错误).但要弄清楚你会检查确切的退出代码是什么样的错误. (2认同)

use*_*001 52

你不需要if语句中的反引号.你可以使用这个检查

if ping -c 1 some_ip_here &> /dev/null
then
  echo 1
else
  echo 0
fi
Run Code Online (Sandbox Code Playgroud)

if命令检查以下命令的退出代码(ping).如果退出代码为零(这意味着命令退出成功),则将执行then块.如果它返回非零退出代码,则将执行else块.

  • @TNT取决于外壳。在bash中,“&>文件”等效于“>文件2>&1”,即重定向标准输出和标准错误。 (2认同)

Fed*_*TIK 23

有高级版本的ping - "fping",它可以定义超时(以毫秒为单位).

#!/bin/bash
IP='192.168.1.1'
fping -c1 -t300 $IP 2>/dev/null 1>/dev/null
if [ "$?" = 0 ]
then
  echo "Host found"
else
  echo "Host not found"
fi
Run Code Online (Sandbox Code Playgroud)

  • 真正.但在几秒钟内.`fping` - 以毫秒为单位,如果您有很多要ping的主机,这很重要. (6认同)
  • 在“unixy”中 ping `-t` 不是为了超时,而是为了 TTL。超时通过-W 指定。注意:这仍然可能阻塞很长时间,例如。如果 DNS 服务器消失并且必须解析 DNS 名称。考虑到最近的攻击,应该考虑这一点。 (3认同)
  • 与这里的许多其他答案一样,这个答案具有反模式“cmd;”。如果 [ $? = 0 ]; then ...` 更好,更惯用的写法是 `if cmd; then ...` -- shell 中 `if` 和其他流程控制语句的目的正是为了运行命令并检查其退出状态。您很少需要直接检查“$?”。 (3认同)
  • 这绝对是一种反模式。 (3认同)

sdk*_*kks 17

我能想到像这样的一个班轮跑

ping -c 1 127.0.0.1 &> /dev/null && echo success || echo fail
Run Code Online (Sandbox Code Playgroud)

将127.0.0.1替换为IP或主机名,将echo命令替换为两种情况下需要执行的操作.

上面的代码将成功,也许尝试使用您知道无法访问的IP或主机名.

像这样:

ping -c 1 google.com &> /dev/null && echo success || echo fail
Run Code Online (Sandbox Code Playgroud)

还有这个

ping -c 1 lolcatz.ninja &> /dev/null && echo success || echo fail
Run Code Online (Sandbox Code Playgroud)

  • 非常好的一个内衬!! (3认同)

小智 11

这是一个完整的 bash 脚本,每 5 秒 ping 一次目标并将错误记录到文件中。

享受!

#!/bin/bash
        
        FILE=errors.txt
        TARGET=192.168.0.1

          touch $FILE
          while true;
          do
            DATE=$(date '+%d/%m/%Y %H:%M:%S')
            ping -c 1 $TARGET &> /dev/null
            if [[ $? -ne 0 ]]; then
              echo "ERROR "$DATE
              echo $DATE >> $FILE
            else
              echo "OK "$DATE
            fi
              sleep 5
          done
Run Code Online (Sandbox Code Playgroud)


小智 5

仅供参考,我只是使用上述方法进行了一些测试,如果我们使用多 ping(10 个请求)

ping -c10 8.8.8.8 &> /dev/null ; 回声 $?

如果 ping 结果中至少有一个可达,则 multi ping 命令的结果将为“0”,如果所有 ping 请求都不可达,则结果为“1”。