如何使用bash测试Internet连接?

时间:2009-05-30 08:45:50

标签: bash connection ping

如何在不ping某些网站的情况下测试互联网连接? 我的意思是,如果有连接但网站已关闭怎么办?是否检查了与世界的联系?

21 个答案:

答案 0 :(得分:107)

没有ping

#!/bin/bash

wget -q --spider http://google.com

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

-q :沉默模式

- 蜘蛛:不要搞定,只需查看网页可用性

$?:shell返回代码

0 :shell“一切正常”代码

没有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

答案 1 :(得分:88)

Ping您的默认网关:

#!/bin/bash
ping -q -w 1 -c 1 `ip r | grep default | cut -d ' ' -f 3` > /dev/null && echo ok || echo error

答案 2 :(得分:25)

超级感谢用户​​ somedrew 在这里发布帖子:https://bbs.archlinux.org/viewtopic.php?id=55485 on 2008-09-20 02:09:48

  

查看/ sys / class / net应该是一种方式

这是我的脚本,用于测试除回送之外的网络连接。 我使用下面的另一个脚本来定期测试我的网站是否可访问。如果无法访问,弹出窗口会提醒我一个问题。

下面的脚本可以防止每当我的笔记本电脑没有连接到网络时,我每五分钟就会收到一次弹出消息。

#!/usr/bin/bash

# Test for network conection
for interface in $(ls /sys/class/net/ | grep -v lo);
do
  if [[ $(cat /sys/class/net/$interface/carrier) = 1 ]]; then OnLine=1; fi
done
if ! [ $OnLine ]; then echo "Not Online" > /dev/stderr; exit; fi

请注意bash的新手:最后的'if'语句测试是否[!]在线,如果是这种情况则退出。请参阅man bash并搜索“表达式可以合并”以获取更多详细信息。

P.S。我觉得ping不是最好用的,因为它的目的是测试到特定主机的连接不测试是否存在任何类型的连接到网络

P.P.S。以上适用于Ubuntu 12.04 / sys可能不存在于其他一些发行版中。见下文:

  

现代Linux发行版包含一个/ sys目录作为虚拟文件系统(sysfs,类似于/ proc,它是一个procfs),它存储并允许修改连接到系统的设备,而许多传统的UNIX和Unix类似操作系统使用/ sys作为内核源代码树的符号链接。[citation needed]

     

来自维基百科https://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard

答案 3 :(得分:21)

适用于MacOSX和Linux:

#!/bin/bash

ping -q -w1 -c1 google.com &>/dev/null && echo online || echo offline

答案 4 :(得分:7)

我之前编写过脚本只需使用telnet连接到端口80,然后传输文本:

HTTP/1.0 GET /index.html

接着是两个CR / LF序列。

如果您返回某种形式的HTTP响应,通常可以假设该网站正在运行。

答案 5 :(得分:6)

最佳答案错过了这样一个事实,即您可以与默认网关建立完美稳定的连接,但这并不意味着您实际上可以在互联网上实现某些目标。 OP询问他/她如何测试与世界的联系。因此,我建议通过将网关IP更改为LAN外部的已知IP(x.y.z.w)来更改最佳答案。

所以答案会变成:

ping -q -w 1 -c 1 x.y.z.w > /dev/null && echo ok || echo error

同时删除命令替换 [1] 的不受欢迎的反对。

如果您只是想在执行某些代码之前确保已连接到世界,您还可以使用:

if ping -q -w 1 -c 1 x.y.z.w > /dev/null; then
    # more code
fi

答案 6 :(得分:5)

执行以下命令检查网站是否已启动,以及Web服务器显示的状态消息:

static func bestMatchFilterdStringArray(inputArray: [String], searchTerm: String) -> [String] { let matchingTerms = inputArray .filter { $0.range(of: searchTerm, options: .caseInsensitive) != nil } .sorted { ($0.hasPrefix(searchTerm) ? 0 : 1) < ($1.hasPrefix(searchTerm) ? 0 : 1) } return matchingTerms } $ curl -Is http://www.google.com |

状态代码“200 OK”表示请求已成功并且网站可以访问。

答案 7 :(得分:4)

如果您的本地名称服务器已关闭,

ping 4.2.2.1

是一个易于记忆的永远在线的IP(它实际上是一个名称服务器,甚至)。

答案 8 :(得分:4)

确保您的网络允许TCP流量进出,然后您可以使用以下命令恢复面向公众的IP

curl ifconfig.co

答案 9 :(得分:3)

top voted answer不适用于MacOS,因此对于mac上的用户,我已经成功测试了这个:

GATEWAY=`route -n get default | grep gateway`
if [ -z "$GATEWAY" ]
  then
    echo error
else
  ping -q -t 1 -c 1 `echo $GATEWAY | cut -d ':' -f 2` > /dev/null && echo ok || echo error
fi

在MacOS High Sierra 10.12.6上测试

答案 10 :(得分:3)

最短路:fping 4.2.2.1 =&gt; “4.2.2.1还活着”

我更喜欢这个,因为它比ping更快,更简洁的输出,缺点是你必须安装它。

您可以使用任何public dns而非特定网站。

fping -q google.com && echo "do something because you're connected!"

-q会返回一个退出代码,所以我只是展示一个运行你在线的东西的例子。

在mac上安装:brew install fping;在ubuntu:sudo apt-get install fping

答案 11 :(得分:2)

@Jesse's answer类似,此选项可能比使用ping的任何解决方案快得多,效率可能略高于@Jesse's answer

find /sys/class/net/ -maxdepth 1 -mindepth 1 ! -name "*lo*" -exec sh -c 'cat "$0"/carrier 2>&1' {} \; | grep -q '1'

Explenation:

此命令使用find-exec*lo*中未命名为/sys/class/net/的所有文件运行命令。这些应该是指向包含有关计算机上可用网络接口信息的目录的链接。

正在运行的命令是sh命令,用于检查这些目录中文件carrier的内容。 $interface/carrier的值有3个含义 - Quoting

  

似乎有三种状态:

     
      
  • ./ carrier不可读(例如在网络管理器中禁用接口时)。
  •   
  • ./ carrier包含“1”(当界面被激活且连接到WiFi网络时)
  •   
  • ./ carrier包含“0”(当界面被激活且未连接到WiFi网络时)
  •   

@Jesse's answer中没有考虑第一个选项。条带化的sh命令是:

# Note: $0 == $interface
cat "$0"/carrier 2>&1

cat用于检查carrier的内容,并将所有输出重定向到标准输出,即使它因为文件不可读而失败也是如此。 如果grep -q在这些文件中找到"1",则表示至少连接了1个接口。 grep -q的退出代码将是最终退出代码。

用法

例如,使用此命令的退出状态,只有在有互联网连接的情况下,才能使用此~/.xprofile启动gnubiff

online() {
    find /sys/class/net/ -maxdepth 1 -mindepth 1 ! -name "*lo*" -exec sh -c 'cat "$0"/carrier 2>&1 > /dev/null | grep -q "1" && exit 0' {} \;
}
online && gnubiff --systemtray --noconfigure &

参考

答案 12 :(得分:2)

此bash脚本会持续检查Internet并在Internet可用时发出哔声。

#!/bin/bash
play -n synth 0.3 sine 800 vol 0.75
while :
do
pingtime=$(ping -w 1 8.8.8.8 | grep ttl)
if [ "$pingtime" = "" ] 
then 
   pingtimetwo=$(ping -w 1 www.google.com | grep ttl) 
   if [ "$pingtimetwo" = "" ] 
   then 
       clear ; echo 'Offline'
   else
       clear ; echo 'Online' ; play -n synth 0.3 sine 800 vol 0.75
   fi 
else
    clear ; echo 'Online' ; play -n synth 0.3 sine 800 vol 0.75
fi
sleep 1
done

答案 13 :(得分:2)

检查Google的索引页面是另一种方法:

#!/bin/bash

WGET="/usr/bin/wget"

$WGET -q --tries=20 --timeout=10 http://www.google.com -O /tmp/google.idx &> /dev/null
if [ ! -s /tmp/google.idx ]
then
    echo "Not Connected..!"
else
    echo "Connected..!"
fi

答案 14 :(得分:2)

Ping旨在完成你想要做的事情。但是,如果站点阻止ICMP echo,那么您可以始终将telnet连接到某个站点的端口80,wget或curl。

答案 15 :(得分:1)

Pong并不意味着服务器上的Web服务正在运行;它只是意味着服务器正在回复ICMP回声。 我建议使用curl并检查其返回值。

答案 16 :(得分:0)

如果您的目标是实际检查 Internet 的访问权限,则该问题的许多现有答案都是有缺陷的。您应该注意的几件事:

  1. 您的计算机可能连接到网络而该网络无法访问互联网
  2. 服务器可能会关闭而整个互联网无法访问
  3. 即使您没有Internet访问权限,强制门户也可能返回任意URL的HTTP响应

考虑到这一点,我相信最好的策略是通过HTTPS连接与几个网站联系,并在其中任何一个响应的情况下返回true。

例如:

connected_to_internet() {
  test_urls="\
  https://www.google.com/ \
  https://www.microsoft.com/ \
  https://www.cloudflare.com/ \
  "

  processes="0"
  pids=""

  for test_url in $test_urls; do
    curl --silent --head "$test_url" > /dev/null &
    pids="$pids $!"
    processes=$(($processes + 1))
  done

  while [ $processes -gt 0 ]; do
    for pid in $pids; do
      if ! ps | grep "^[[:blank:]]*$pid[[:blank:]]" > /dev/null; then
        # Process no longer running
        processes=$(($processes - 1))
        pids=$(echo "$pids" | sed --regexp-extended "s/(^| )$pid($| )/ /g")

        if wait $pid; then
          # Success! We have a connection to at least one public site, so the
          # internet is up. Ignore other exit statuses.
          kill -TERM $pids > /dev/null 2>&1 || true
          wait $pids
          return 0
        fi
      fi
    done
    # wait -n $pids # Better than sleep, but not supported on all systems
    sleep 0.1
  done

  return 1
}

用法:

if connected_to_internet; then
  echo "Connected to internet"
else
  echo "No internet connection"
fi

有关此方法的一些说明:

  1. 对于我上面概述的所有误报和否定,它都很强大
  2. 所有请求并行发生以最大化速度
  3. 如果您在技术上可以访问互联网,但DNS无法正常运行,或者您的网络设置被弄乱了,它将返回false,我认为在大多数情况下这样做是合理的。

答案 17 :(得分:0)

在Bash中,通过 / dev / { udp tcp } / 主机 / 端口

if echo -n >/dev/tcp/8.8.8.8/53; then
  echo 'Internet available.'
else
  echo 'Offline.'
fi

答案 18 :(得分:0)

与此处发布的任何解决方案相比,它明显更快,并且还可以用于测试特定主机

诀窍是使用比netplan使用的DNS解析器少的 DNS解析器来解析IP:

ping

答案 19 :(得分:0)

如果你想处理强制门户,你可以这样做oneliner:

if [[ $(curl -s -D - http://www.gstatic.com/generate_204 2>/dev/null | head -1 | cut -d' ' -f 2) == "204" ]]; then
  echo 'online'
else
  echo 'offline'
fi

或者,如果您想要一些更具可读性的东西,可以区分强制门户与缺乏信号:

function is_online() {
  # Test signal
  local response
  response=$(curl --silent --dump-header - http://www.gstatic.com/generate_204 2> /dev/null)
  if (($? != 0)); then return 2; fi
  # Test captive portal
  local status=$(echo $response | head -1 | cut -d' ' -f 2)
  ((status == "204"))
}
is_online && echo online || echo offline

答案 20 :(得分:-17)

ping www.google.com
ping www.yahoo.com
ping www.facebook.com
ping www.stackoverflow.com

这样做,你可以非常肯定:)