128

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

4

20 回答 20

156

没有 ping

#!/bin/bash

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

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

-q:静音模式

--spider : 不知道,只是检查页面可用性

美元?: 外壳返回码

0:外壳“一切正常”代码

没有 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
于 2014-11-08T18:01:49.260 回答
97

ping 默认网关:

#!/bin/bash
ping -q -w 1 -c 1 `ip r | grep default | cut -d ' ' -f 3` > /dev/null && echo ok || echo error
于 2009-05-31T15:04:55.757 回答
31

超级感谢用户​​ 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 并搜索“可以组合表达式”。

PS 我觉得 ping 不是在这里使用的最佳选择,因为它旨在测试与特定主机的连接,而不是测试是否存在与任何类型网络的连接。

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

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

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

于 2013-02-18T15:09:32.637 回答
27

这适用于 MacOSX 和 Linux:

#!/bin/bash

ping -q -c1 google.com &>/dev/null && echo online || echo offline
于 2016-06-19T14:29:20.483 回答
15

在 Bash 中,通过/dev/ { udp , tcp } / host / port使用它的网络包装器:

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

:是 Bash 无操作,因为您只想测试连接,而不是处理。)

于 2019-05-14T20:33:19.117 回答
8

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

所以答案会变成:

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
于 2018-02-01T10:17:57.747 回答
7

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

HTTP/1.0 GET /index.html

其次是两个 CR/LF 序列。

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

于 2009-05-30T08:50:24.113 回答
7

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

curl -Is http://www.google.com | head -1 HTTP/1.1 200 OK

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

于 2017-12-13T13:53:07.570 回答
6

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

curl ifconfig.co
于 2017-11-19T09:52:14.953 回答
5

投票最多的答案不适用于 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 上测试

于 2018-01-12T15:14:30.710 回答
4

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

平 4.2.2.1

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

于 2009-05-31T02:43:52.760 回答
4

此 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
于 2017-09-21T06:46:36.293 回答
3

最短的方法:fping 4.2.2.1=>“4.2.2.1 还活着”

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

您可以使用任何公共 dns而不是特定网站。

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

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

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

于 2017-10-11T00:40:34.047 回答
2

Ping 旨在完成您想要做的事情。但是,如果站点阻止了 ICMP 回显,那么您始终可以远程登录到某个站点的 80 端口、wget 或 curl。

于 2009-05-31T15:16:48.930 回答
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
于 2014-12-03T18:18:47.420 回答
2

与@Jesse 的回答类似,此选项可能比使用的任何解决方案都快得多,ping并且可能比@Jesse 的回答更有效。

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

解释:

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

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

似乎有三种状态:

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

@Jesse 的回答中没有考虑第一个选项。删除的sh命令是:

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

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

用法

例如,使用这个命令的退出状态,你可以使用它来启动一个gnubiff~/.xprofile只有当你有互联网连接时。

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 &

参考

于 2017-05-31T09:28:47.707 回答
1

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

于 2009-06-02T13:55:25.487 回答
1

如果您的目标是实际检查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 ,我认为在大多数情况下这是合理的做法
于 2018-08-15T17:23:39.713 回答
0

为了获得最快的结果,ping DNS 服务器

ping -c1 "8.8.8.8" &>"/dev/null"

if [[ "${?}" -ne 0 ]]; then
    echo "offline"
elif [[ "${#args[@]}" -eq 0 ]]; then
    echo "online"
fi

可作为独立命令使用:linkStatus

于 2019-10-13T21:57:46.160 回答
0

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

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
于 2021-04-21T15:32:16.930 回答