【问题标题】:How can I check Internet access using a Bash script on Linux?如何在 Linux 上使用 Bash 脚本检查 Internet 访问?
【发布时间】:2013-06-21 21:21:36
【问题描述】:

在我的学校,网络不可用(每天晚上 23:00 之后学校会断网,让我们睡觉>..ping -w1 ...。

也就是说,当我使用:ping -q -w1 -c1 8.8.8.8 来检查 Internet 连接是否启动/关闭时,它将在那里没有任何输出并且不会退出,就像我使用单个 cat 一样。

我不知道为什么会这样,但我认为问题与 school-internet-service 有关。有什么建议吗? (我认为wget 可能是一个不错的选择,但我该如何使用呢?)

【问题讨论】:

标签: linux bash wifi ping


【解决方案1】:

使用 wget:

#!/bin/bash

wget -q --tries=10 --timeout=20 --spider http://google.com
if [[ $? -eq 0 ]]; then
        echo "Online"
else
        echo "Offline"
fi

【讨论】:

  • 效果很好。非常感谢!我的旧版本缺少--tries,因此无法使用。
  • 就个人而言,我通过创建wget -q --tries=10 --timeout=20 -O - http://google.com > /dev/null 来增强此模式。这会丢弃输出,这意味着文件不会被遗弃,写入权限也不会出现任何问题。
  • 你真的应该使用--spider 选项,因为它会发送一个http HEAD 请求,而不是一个http GET 请求。现在,在这种情况下,您正在检查 google.com,这是一个非常轻量级的页面,因此它可能没问题。但作为一般规则,如果您只是想检查某些内容是否可用而不实际下载,则应使用HEAD 请求。我已相应地添加到答案中。
【解决方案2】:

如果学校真的关闭了他们的路由器,而不是将所有流量重定向到“你为什么不睡觉”页面,则无需下载整个网页或发送 HTTP 标头。您所要做的就是建立连接并检查是否有人在听。

nc -z 8.8.8.8 53

这将输出“连接到 8.8.8.8 端口 53 [tcp/domain] 成功!”如果有人在听,则返回值 0。

如果你想在 shell 脚本中使用它:

nc -z 8.8.8.8 53  >/dev/null 2>&1
online=$?
if [ $online -eq 0 ]; then
    echo "Online"
else
    echo "Offline"
fi

【讨论】:

  • 这是最快的方法,它 ping dns 服务器而不是获取 google 的网站数据。竖起大拇指。
  • 在这里使用超时可能会很好 nc -z -w 5 8.8.8.8 53 >/dev/null 2>&1
【解决方案3】:

用途:

#!/bin/bash

INTERNET_STATUS="UNKNOWN"
TIMESTAMP=`date +%s`
while [ 1 ]
 do
    ping -c 1 -W 0.7 8.8.4.4 > /dev/null 2>&1
    if [ $? -eq 0 ] ; then
        if [ "$INTERNET_STATUS" != "UP" ]; then
            echo "UP   `date +%Y-%m-%dT%H:%M:%S%Z` $((`date +%s`-$TIMESTAMP))";
            INTERNET_STATUS="UP"
        fi
    else
        if [ "$INTERNET_STATUS" = "UP" ]; then
            echo "DOWN `date +%Y-%m-%dT%H:%M:%S%Z` $((`date +%s`-$TIMESTAMP))";
            INTERNET_STATUS="DOWN"
        fi
    fi
    sleep 1
 done;

输出将产生如下内容:

./internet_check.sh

UP   2016-05-10T23:23:06BST 4
DOWN 2016-05-10T23:23:25BST 19
UP   2016-05-10T23:23:32BST 7

行尾的数字表示前一个状态的持续时间,即向上 19 秒,向下 7 秒。

【讨论】:

  • 欢迎来到 Stack Overflow!虽然这段代码可能会回答这个问题,但最好包含一些上下文,解释它的如何工作以及何时使用它。从长远来看,纯代码的答案没有用处。
  • 在几分钟内经历了很多起伏。虽然 DropBox 在线并且可以上网...请参阅 unix.stackexchange.com/a/190610/19694,他们提到 nc 比使用 ping 更好,因为很多主机商也禁用了 ICMP。
  • 我看不到如何使用上面的代码获得持续时间。我试过了,每行的“持续时间”单调增长。 TIMESTAMP 不是每次循环都要重置吗?
【解决方案4】:

使用超时选项-t

ping -q -t 5 -w1 -c1 8.8.8.8 t

【讨论】:

  • 这个解决方案的一个问题是,一些网络可能会阻止传出的 ping(我的大学有这样做的著名记录)。不过,OP 似乎并非如此。
  • @umlaeute,在这种情况下,您可以使用wget http://google.com 甚至(更好更简单)curl
【解决方案5】:

没有 wget

#!/bin/bash

echo -e "GET http://google.com HTTP/1.0\n\n" | nc google.com 80 > /dev/null 2>&1

if [ $? -eq 0 ]; then
    echo "Online"
else
    echo "Offline"
fi

享受;)

【讨论】:

    【解决方案6】:

    安装 fping:> 问题比 ping 少。

    fping google.com | grep alive
    

    使用,例如,像:

    #!/bin/bash
    
    itest=$(fping google.com | grep alive)
    
    while [ "$itest" == "" ]
            do
            sleep 5
            itest=$(fping google.com | grep alive)
    done
    echo now online
    

    【讨论】:

    • fping 需要在运行示例之前安装。
    【解决方案7】:

    使用上面的示例。我写了这个脚本来记录你的连接状态: https://gist.github.com/cganterh/ffc2fffa8263857cbece

    首先,将以下代码保存到name.sh 文件中。

    #!/bin/bash
    
    while true
    do
        wget -q --tries=10 --timeout=20 -O - http://google.com > /dev/null
        if [[ $? -eq 0 ]]; then
            echo $(date) "1" | tee -a log.csv
        else
            echo $(date) "0" | tee -a log.csv
        fi
        sleep 5
    done
    

    然后,在终端执行name.sh文件,然后查看同一文件夹log.csv的日志状态信息。

    【讨论】:

      【解决方案8】:

      我决定将之前的几个答案结合起来,这样我以后就可以创建一个显示起起落落及其持续时间的图:

      #!/bin/bash
      #
      # pinger is a bash shell script that monitors the network
      # status every 15 seconds and records if it is up '1' or down '0'
      # into the file log.csv from whence it may be plotted.
      #
      # author: J. W. Wooten, Ph.D.
      # since: 11/12/2019
      # version: 1.0
      #
      TIMESTAMP=`date +%s`
      while [ 1 ]
        do
          nc -z -w 5 8.8.8.8 53  >/dev/null 2>&1
      online=$?
          TIME=`date +%s`
          if [ $online -eq 0 ]; then
            echo "`date +%Y-%m-%d_%H:%M:%S_%Z` 1 $(($TIME-$TIMESTAMP))" | tee -a log.csv
          else
            echo "`date +%Y-%m-%d_%H:%M:%S_%Z` 0 $(($TIME-$TIMESTAMP))" | tee -a log.csv
          fi
          TIMESTAMP=$TIME
          sleep 15
        done;
      

      这将每 15 秒输出到一个 CSV 文件。使用 Excel 或 Numbers,您可以读取文件并创建一个图表,该图表将显示 Internet 连接何时不可用以及持续时间。如果它从您的睡眠间隔发生变化,那么它正在花费时间尝试连接。我希望添加在下一次检测到网络关闭时向我发送文本的功能。

      【讨论】:

        【解决方案9】:

        Majal's solution 的一个变体只是为了测试 ping 的返回代码,如果站点响应,则返回 0,如果没有回复,则返回 1,如果网络不可达,则返回 2。

            ping -c 1 -t 5 8.8.8.8 2&>1
            rc=$?
            [[ $rc -eq 0 ]] && { echo "Connected to the Internet" ; exit 0 ; } \
         || [[ $rc -eq 1 ]] && { echo "No reply from Google DNS" ; exit 1 ; } \
         || [[ $rc -eq 2 ]] && { echo "Network unreachable" ; exit 2 ; }
        

        使用ping的好处是不需要下载任何东西,提高了测试速度。

        【讨论】:

          【解决方案10】:

          可靠的旧 ping 在单独的 Bash 脚本中:

          #!/bin/bash
          ipaddr='8.8.8.8' # Google's public DNS server
          [[ -z `ping -c1 $ipaddr |& grep -o 'Network is unreachable'` ]] || exit 1
          [[ -z `ping -c3 $ipaddr |& grep -o '100% packet loss'` ]] && exit 0 || exit 1
          

          把它放在一个单独的脚本中。它将处理不同的网络情况,例如 (1) 未连接到网络,(2) 已连接到网络,但无法访问 Internet(或至少 Google),以及 (3) 连接到互联网。


          您可以稍后使用脚本的exit code 来检查连接性,例如

          ~$ script-name && echo online || echo offline
          

          【讨论】:

            猜你喜欢
            • 2016-02-25
            • 2017-10-09
            • 1970-01-01
            • 2012-01-18
            • 1970-01-01
            • 2018-08-05
            • 2015-04-03
            • 2022-01-15
            • 2015-09-17
            相关资源
            最近更新 更多