目录
- [Linux 脚本实现「联网才工作」:拒绝离线分析的实用方案](#Linux 脚本实现「联网才工作」:拒绝离线分析的实用方案)
-
- 一、核心需求拆解
- 二、两种实用的网络判断方案
-
- [2.1. 用 ping 检测基础网络连通性](#2.1. 用 ping 检测基础网络连通性)
-
- [2.1.1 关键参数说明](#2.1.1 关键参数说明)
- [2.1.2 脚本示例(核心逻辑)](#2.1.2 脚本示例(核心逻辑))
- [2.2. 用 curl/wget 检测业务级连通性](#2.2. 用 curl/wget 检测业务级连通性)
-
- [2.2.1 关键参数说明(以 curl 为例)](#2.2.1 关键参数说明(以 curl 为例))
- [2.2.2 脚本示例(核心逻辑)](#2.2.2 脚本示例(核心逻辑))
- 三、进阶优化:提升脚本健壮性
-
- [3.1. 多目标检测(防止单一地址宕机)](#3.1. 多目标检测(防止单一地址宕机))
- [3.2. 增加日志记录(方便排查)](#3.2. 增加日志记录(方便排查))
- [3.3. 防止脚本被篡改(权限控制)](#3.3. 防止脚本被篡改(权限控制))
- 四、完整示例:最终可用脚本
- 五、总结
Linux 脚本实现「联网才工作」:拒绝离线分析的实用方案
在实际开发中,我们常会遇到这样的需求:脚本 / 程序仅在确认网络连通时才执行核心逻辑,一旦检测到离线,直接退出运行 ------ 这既能避免离线状态下的无效执行,更能防止他人通过离线环境篡改或分析程序(比如恶意调试、逆向破解)。今天就带大家拆解这种需求的实现思路,提供两种可靠的网络判断方案,新手也能直接复用。
一、核心需求拆解
我们需要的本质是 "脚本启动前的网络预检",满足三个关键条件:
- 快速判断:不能因网络检测耗时过长影响程序启动;
- 结果可靠:避免因 "临时网络波动" 或 "单一目标不可达" 导致误判;
- 低依赖:尽量使用 Linux 系统预装工具(如 ping、curl),减少额外安装成本。
二、两种实用的网络判断方案
Linux 系统中,ping
(ICMP 协议)和curl/wget
(TCP 协议)是最常用的网络检测工具,分别适用于不同场景,我们逐一讲解。
2.1. 用 ping 检测基础网络连通性
ping
是最基础的网络检测工具,通过发送 ICMP 数据包判断目标是否可达,优点是速度快、系统默认预装,适合检测 "是否能连接公网 / 网关"。
2.1.1 关键参数说明
-c 2
:只发送 2 个数据包(减少检测耗时);-W 3
:每个数据包超时时间 3 秒(避免无限等待);- 目标选择:建议用公网稳定地址(如114.114.114.114,8.8.8.8),避免用网关(可能被篡改路由绕开)。
2.1.2 脚本示例(核心逻辑)
#!/bin/bash
# 网络检测目标(可替换为你的业务依赖地址)
CHECK_URL="114.114.114.114"
# 执行ping检测
ping -c 2 -W 3 $CHECK_URL > /dev/null 2>&1
# 判断结果:$?为上一条命令的返回值,0表示成功(网络通),非0表示失败
if [ $? -eq 0 ]; then
echo "[$(date +%Y-%m-%d %H:%M:%S)] 网络正常,启动核心程序..."
# 这里写你的核心业务逻辑,比如执行程序、启动服务
# ./your_program --param xxx
else
echo "[$(date +%Y-%m-%d %H:%M:%S)] 网络离线,程序退出!"
# 直接退出,退出码1表示"网络异常"
exit 1
fi
2.2. 用 curl/wget 检测业务级连通性
有些场景下,ping
可能被防火墙禁用(ICMP 协议拦截),此时更可靠的方式是用curl/wget
检测具体业务地址的 TCP 连通性(比如你的后端 API、官网),同时能验证服务是否正常响应。
2.2.1 关键参数说明(以 curl 为例)
-s
:静默模式,不输出多余日志;-o /dev/null
:将响应内容丢弃(只关注状态码);-w "%{http_code}"
:仅输出 HTTP 状态码(200 = 正常,3xx = 重定向,4xx/5xx = 异常);-m 5
:超时时间 5 秒。
2.2.2 脚本示例(核心逻辑)
#!/bin/bash
# 检测业务地址(替换为你的实际地址)
BUSINESS_URL="https://api.yourdomain.com/health"
# 执行curl检测,获取HTTP状态码
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" -m 5 $BUSINESS_URL)
# 判断状态码:200/301/302均视为"网络+服务正常"
if [[ $HTTP_CODE -eq 200 || $HTTP_CODE -eq 301 || $HTTP_CODE -eq 302 ]]; then
echo "[$(date +%Y-%m-%d %H:%M:%S)] 网络及业务服务正常,启动程序..."
# 执行核心逻辑
# ./your_program
else
echo "[$(date +%Y-%m-%d %H:%M:%S)] 网络离线或服务异常(状态码:$HTTP_CODE),程序退出!"
exit 1
fi
# 如果用wget,可替换为以下命令(--spider模拟爬取,不下载内容):
# wget --spider -q -T 5 $BUSINESS_URL
# if [ $? -eq 0 ]; then ... fi
三、进阶优化:提升脚本健壮性
为了让方案更实用,我们可以增加 3 个优化点,避免 "误判" 和 "漏洞":
3.1. 多目标检测(防止单一地址宕机)
如果只检测一个目标,可能因目标自身故障导致程序误退出,建议同时检测 2-3 个地址,只要有一个通就算 "网络正常":
#!/bin/bash
# 多检测目标(公网DNS+业务地址)
TARGETS=("114.114.114.114" "8.8.8.8" "https://api.yourdomain.com")
SUCCESS=0
# 遍历目标检测,只要有一个成功就标记为正常
for target in "${TARGETS[@]}"; do
if [[ $target =~ ^https?:// ]]; then
# 若是HTTP地址,用curl检测
curl -s -o /dev/null -m 3 $target > /dev/null 2>&1
else
# 若是IP,用ping检测
ping -c 1 -W 2 $target > /dev/null 2>&1
fi
if [ $? -eq 0 ]; then
SUCCESS=1
break
fi
done
if [ $SUCCESS -eq 1 ]; then
echo "网络正常,启动程序..."
else
echo "所有目标均不可达,程序退出!"
exit 1
fi
3.2. 增加日志记录(方便排查)
离线退出时,将日志写入文件,后续可追溯 "何时离线""原因是什么":
# 日志文件路径
LOG_FILE="/var/log/network.log"
# 替换之前的echo为日志写入
if [ $? -eq 0 ]; then
echo "[$(date +%Y-%m-%d %H:%M:%S)] 网络正常,启动程序..." | tee -a $LOG_FILE
else
echo "[$(date +%Y-%m-%d %H:%M:%S)] 网络离线,程序退出!" | tee -a $LOG_FILE
exit 1
fi
3.3. 防止脚本被篡改(权限控制)
为避免他人修改脚本绕过网络检测,可设置脚本为 "只读",并限制执行权限:
# 给脚本设置权限:所有者可读写,其他用户只读(不可修改)
chmod 755 script.sh
# 或更严格:只有所有者可执行+读写,其他人无权限
chmod 700 script.sh
四、完整示例:最终可用脚本
整合以上优化,给出一个 "多目标检测 + 日志 + 权限控制" 的完整脚本,可直接替换./your_program
为你的实际程序:
#!/bin/bash
# 功能:仅联网时启动程序,离线直接退出(含日志记录)
# 配置项(根据需求修改)
DETECTION_TARGETS=("114.114.114.114" "https://api.baidu.com") # 检测目标
LOG_FILE="/var/log/network_check.log" # 日志路径
CORE_PROGRAM="./your_program" # 核心程序路径
# 1. 多目标网络检测
check_network() {
local success=0
for target in "${DETECTION_TARGETS[@]}"; do
if [[ $target =~ ^https?:// ]]; then
# HTTP目标用curl检测
curl -s -o /dev/null -m 3 $target > /dev/null 2>&1
else
# IP目标用ping检测
ping -c 1 -W 2 $target > /dev/null 2>&1
fi
if [ $? -eq 0 ]; then
success=1
break
fi
done
echo $success
}
# 2. 主逻辑
main() {
local network_status=$(check_network)
if [ $network_status -eq 1 ]; then
echo "[$(date +%Y-%m-%d %H:%M:%S)] 网络正常,启动核心程序..." | tee -a $LOG_FILE
# 启动核心程序(若程序退出码非0,也记录日志)
$CORE_PROGRAM
if [ $? -ne 0 ]; then
echo "[$(date +%Y-%m-%d %H:%M:%S)] 核心程序异常退出!" | tee -a $LOG_FILE
fi
else
echo "[$(date +%Y-%m-%d %H:%M:%S)] 网络离线,程序退出!" | tee -a $LOG_FILE
exit 1
fi
}
# 执行主逻辑
main
五、总结
- 场景选择 :
ping
适合快速检测基础连通性,curl/wget
适合 ICMP 被禁或需验证业务服务的场景; - 关键原则:用多目标检测避免误判,加日志方便排查,设权限防止篡改;
- 扩展思路 :若需更严格的防离线,可结合 "检测公网时间同步"(
ntpdate
)或 "绑定特定网卡 MAC",进一步提升安全性。 - 脚本加密 :这部分就不再本文细说了,要了解的朋友可以到之前写的文章里看一看: shell脚本加密方法