You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

存储公网IP的文件为何有时为空?OpenWRT脚本问题求助

问题排查与解决

1. nslookup输出空行导致[! -s]判断失效

这是最可能的原因:当DNS查询超时、服务器无响应时,后续的grep/awk没抓到有效IP,反而输出了空行。空行写入/tmp/currentip后,文件大小为1(包含换行符),此时[! -s /tmp/currentip]会判定文件非空,直接进入IP对比分支。因为空行和/tmp/oldip里的有效IP内容不同,脚本触发邮件发送,就会出现空内容邮件;下一次查询成功时,又会因为IP和之前的空行不同,发送一封正常IP的邮件。

验证方式

手动测试场景:

# 写入空行到测试文件
echo -e "" > /tmp/testip
# 查看文件大小
ls -l /tmp/testip
# 执行判断逻辑
[! -s /tmp/testip ] && echo "空文件" || echo "非空文件"

你会发现带空行的文件会被判定为非空,触发后续对比逻辑。

修复办法

修改IP提取逻辑,确保只写入有效IP,过滤空内容:

# 用awk直接过滤出符合格式的公网IP,跳过本地回环地址
nslookup myip.opendns.com resolver1.opendns.com | awk '/Address:/ && $2 != "127.0.0.1" {print $2}' > /tmp/currentip
# 额外校验:如果文件内容不是有效IP,直接清空文件
grep -qE '^([0-9]{1,3}\.){3}[0-9]{1,3}$' /tmp/currentip || rm -f /tmp/currentip

2. cron执行环境缺失必要路径

OpenWRT的cron默认PATH范围很窄,可能找不到nslookup或mail命令,导致命令执行失败,输出空内容到/tmp/currentip。

验证方式

在脚本开头添加日志,记录cron的执行环境PATH:

echo "$(date): PATH is $PATH" >> /tmp/cron_debug.log

等待cron执行几次后,查看/tmp/cron_debug.log,如果日志里没有/usr/bin这类常见命令路径,就是问题所在。

修复办法

在脚本最开头指定完整路径:

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

或者直接使用命令的绝对路径,比如/usr/bin/nslookup、/usr/bin/mail。

3. /tmp临时文件系统异常

OpenWRT的/tmp是基于RAM的文件系统,偶尔会因为内存不足导致文件写入不完整,出现空文件或损坏文件,触发脚本逻辑异常。

修复办法

  • 将oldip移到非临时目录,比如/etc/oldip(确保脚本有写入权限);
  • 给IP添加格式校验,只有符合IP格式的内容才保留:
NEW_IP=$(cat /tmp/currentip 2>/dev/null)
if ! echo "$NEW_IP" | grep -qE '^([0-9]{1,3}\.){3}[0-9]{1,3}$'; then
    # 无效IP,用旧IP替代
    if [ -f "/etc/oldip" ]; then
        cp /etc/oldip /tmp/currentip
    fi
fi

4. 脚本逻辑漏洞

如果你的脚本把邮件发送逻辑放在了条件判断外面,或者在覆盖currentip之前就发送邮件,也会出现空邮件。

优化后的脚本逻辑示例

重新梳理逻辑,先确保拿到有效IP,再对比发送邮件:

#!/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

OLD_IP_FILE="/etc/oldip"
CURRENT_IP_FILE="/tmp/currentip"

# 获取公网IP
nslookup myip.opendns.com resolver1.opendns.com | awk '/Address:/ && $2 != "127.0.0.1" {print $2}' > "$CURRENT_IP_FILE"

# 校验IP有效性
NEW_IP=$(cat "$CURRENT_IP_FILE" 2>/dev/null)
if ! echo "$NEW_IP" | grep -qE '^([0-9]{1,3}\.){3}[0-9]{1,3}$'; then
    # 无效IP,用旧IP替代(如果存在)
    if [ -f "$OLD_IP_FILE" ]; then
        NEW_IP=$(cat "$OLD_IP_FILE")
        echo "$NEW_IP" > "$CURRENT_IP_FILE"
    else
        # 第一次执行无旧IP,直接退出
        exit 1
    fi
fi

# 对比IP是否变更
if [ -f "$OLD_IP_FILE" ]; then
    OLD_IP=$(cat "$OLD_IP_FILE")
    if [ "$NEW_IP" != "$OLD_IP" ]; then
        # 发送邮件
        echo "新公网IP: $NEW_IP" | mail -s "IP已变更" your@email.com
        # 更新旧IP
        echo "$NEW_IP" > "$OLD_IP_FILE"
    fi
else
    # 第一次执行,初始化旧IP文件
    echo "$NEW_IP" > "$OLD_IP_FILE"
fi

内容的提问来源于stack exchange,提问作者jbweld

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 20:45:40