soarli

路由器折腾记:如何将老毛子 (Padavan) 固件的 Server酱推送彻底改造为 iOS Bark 推送
在使用老毛子(Padavan/PDCN)固件的路由器时,自带的“设备上下线提醒”和“IP变动提醒”功能非常实用,能...
扫描右侧二维码阅读全文
19
2026/03

路由器折腾记:如何将老毛子 (Padavan) 固件的 Server酱推送彻底改造为 iOS Bark 推送

在使用老毛子(Padavan/PDCN)固件的路由器时,自带的“设备上下线提醒”和“IP变动提醒”功能非常实用,能够让我们时刻掌握网络状态。但是,固件内置的推送方式大多是 Server酱

随着 Server酱 政策的调整以及微信推送的限制增加,对于 iOS 用户来说,使用原生的 Bark 显然是更优雅、更及时、也更免费的选择。

今天这篇文章,就带大家把老毛子固件里古老的 Server酱 脚本,彻底换血改造成支持自定义图标、自定义分组的 Bark 原生推送!

为什么要重构脚本?

很多朋友尝试直接把脚本里的 sc.ftqq.com 替换成 Bark 的链接,结果发现推送经常失败,或者推送过来的设备名称变成了乱码。

原因在于:原版的脚本使用的是简单的 GET 请求拼接 URL 的方式发送数据。当遇到包含空格、中文或特殊符号的设备名称时,URL 编码极容易出错并导致请求截断。

我们的解决方案:使用 curlPOST 请求!
通过改写底层的发送逻辑,使用 POST 表单提交数据,不仅完美解决了乱码和截断问题,还能让我们极其方便地接入 Bark 的高级特性(比如:消息分组 group 和自定义图标 icon)。

核心改造脚本:宿舍路由器状态通知定制版

以下是我目前正在使用的完整脚本。在这个版本中,我指定了 Bark 的专属 URL,设置了“宿舍路由器状态通知”的分组,并为推送配上了一个专属的路由器小图标。

完整代码

#!/bin/bash
# 此脚本路径:/etc/storage/serverchan_script.sh
# 适用平台:老毛子 Padavan (PDCN)
# 功能:替换原带的 Server酱 为 Bark iOS 原生推送

source /etc/storage/script/init.sh
export PATH='/etc/storage/bin:/tmp/script:/etc/storage/script:/opt/usr/sbin:/opt/usr/bin:/opt/sbin:/opt/bin:/usr/local/sbin:/usr/sbin:/usr/bin:/sbin:/bin'
export LD_LIBRARY_PATH=/lib:/opt/lib

# ========= Bark 自定义配置区 =========
# 请将这里的 bark_url 替换为你自己的专属链接
bark_url="https://api.day.app/15cKb6wWAgNNWmuVBmnvXj"
bark_title="宿舍路由器状态通知"
bark_group="宿舍路由器状态通知"
# 自定义推送图标
bark_icon="https://lab.soarli.top/imgs/icons/ss_router.webp"
# =====================================

serverchan_enable=`nvram get serverchan_enable`
serverchan_enable=${serverchan_enable:-"0"}
serverchan_notify_1=`nvram get serverchan_notify_1`
serverchan_notify_2=`nvram get serverchan_notify_2`
serverchan_notify_3=`nvram get serverchan_notify_3`
serverchan_notify_4=`nvram get serverchan_notify_4`
user_agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
mkdir -p /tmp/var
resub=1

# 获得外网地址
    arIpAddress() {
    curltest=`which curl`
    if [ -z "$curltest" ] || [ ! -s "`which curl`" ] ; then
        wget -T 5 -t 3 --user-agent "$user_agent" --quiet --output-document=- "http://members.3322.org/dyndns/getip" | grep -E -o '([0-9]+\.){3}[0-9]+' | head -n1 | cut -d' ' -f1
    else
        curl -L --user-agent "$user_agent" -s "http://members.3322.org/dyndns/getip" | grep -E -o '([0-9]+\.){3}[0-9]+' | head -n1 | cut -d' ' -f1
    fi
    }
# 读取最近外网地址
    lastIPAddress() {
        inter="/etc/storage/lastIPAddress"
        cat $inter
    }

while [ "$serverchan_enable" = "1" ];
do
serverchan_enable=`nvram get serverchan_enable`
serverchan_enable=${serverchan_enable:-"0"}
serverchan_notify_1=`nvram get serverchan_notify_1`
serverchan_notify_2=`nvram get serverchan_notify_2`
serverchan_notify_3=`nvram get serverchan_notify_3`
serverchan_notify_4=`nvram get serverchan_notify_4`
curltest=`which curl`
ping_text=`ping -4 223.5.5.5 -c 1 -w 2 -q`
ping_time=`echo $ping_text | awk -F '/' '{print $4}'| awk -F '.' '{print $1}'`
ping_loss=`echo $ping_text | awk -F ', ' '{print $3}' | awk '{print $1}'`

if [ ! -z "$ping_time" ] ; then
    echo "ping:$ping_time ms 丢包率:$ping_loss"
 else
    echo "ping:失效"
fi

if [ ! -z "$ping_time" ] ; then
echo "online"

# 【功能1:互联网 IP 变动提醒】
if [ "$serverchan_notify_1" = "1" ] ; then
    hostIP=$(arIpAddress)
    hostIP=`echo $hostIP | head -n1 | cut -d' ' -f1`
    if [ "$hostIP"x = "x"  ] ; then
        curltest=`which curl`
        if [ -z "$curltest" ] || [ ! -s "`which curl`" ] ; then
            [ "$hostIP"x = "x"  ] && hostIP=`wget -T 5 -t 3 --user-agent "$user_agent" --quiet --output-document=- "http://members.3322.org/dyndns/getip" | grep -E -o '([0-9]+\.){3}[0-9]+' | head -n1 | cut -d' ' -f1`
            [ "$hostIP"x = "x"  ] && hostIP=`wget -T 5 -t 3 --user-agent "$user_agent" --quiet --output-document=- "ip.3322.net" | grep -E -o '([0-9]+\.){3}[0-9]+' | head -n1 | cut -d' ' -f1`
            [ "$hostIP"x = "x"  ] && hostIP=`wget -T 5 -t 3 --user-agent "$user_agent" --quiet --output-document=- "https://www.ipip.net/" | grep "IP地址" | grep -E -o '([0-9]+\.){3}[0-9]+' | head -n1 | cut -d' ' -f1`
            [ "$hostIP"x = "x"  ] && hostIP=`wget -T 5 -t 3 --user-agent "$user_agent" --quiet --output-document=- "http://pv.sohu.com/cityjson?ie=utf-8" | grep -E -o '([0-9]+\.){3}[0-9]+' | head -n1 | cut -d' ' -f1`
        else
            [ "$hostIP"x = "x"  ] && hostIP=`curl -L --user-agent "$user_agent" -s "http://members.3322.org/dyndns/getip" | grep -E -o '([0-9]+\.){3}[0-9]+' | head -n1 | cut -d' ' -f1`
            [ "$hostIP"x = "x"  ] && hostIP=`curl -L --user-agent "$user_agent" -s ip.3322.net | grep -E -o '([0-9]+\.){3}[0-9]+' | head -n1 | cut -d' ' -f1`
            [ "$hostIP"x = "x"  ] && hostIP=`curl -L --user-agent "$user_agent" -s "https://www.ipip.net" | grep "IP地址" | grep -E -o '([0-9]+\.){3}[0-9]+' | head -n1 | cut -d' ' -f1`
            [ "$hostIP"x = "x"  ] && hostIP=`curl -L --user-agent "$user_agent" -s http://pv.sohu.com/cityjson?ie=utf-8 | grep -E -o '([0-9]+\.){3}[0-9]+' | head -n1 | cut -d' ' -f1`
        fi
    fi
    lastIP=$(lastIPAddress)
    if [ "$lastIP" != "$hostIP" ] && [ ! -z "$hostIP" ] ; then
    sleep 60
        hostIP=$(arIpAddress)
        hostIP=`echo $hostIP | head -n1 | cut -d' ' -f1`
        lastIP=$(lastIPAddress)
    fi
    if [ "$lastIP" != "$hostIP" ] && [ ! -z "$hostIP" ] ; then
        logger -t "【互联网 IP 变动】" "目前 IP: ${hostIP}"
        
        # Bark 推送:POST 请求处理
        body="互联网IP变动:${hostIP}"
        curl -L -s -X POST -d "title=${bark_title}" -d "body=${body}" -d "group=${bark_group}" -d "icon=${bark_icon}" "${bark_url}" &
        
        logger -t "【Bark推送】" "互联网IP变动:${hostIP}"
        echo -n $hostIP > /etc/storage/lastIPAddress
    fi
fi

# 【功能2:新设备加入提醒】
if [ "$serverchan_notify_2" = "1" ] ; then
    touch /tmp/var/newhostname.txt
    echo "接入设备名称" > /tmp/var/newhostname.txt
    cat /tmp/static_ip.inf | grep -v "^$" | awk -F "," '{ if ( $6 == 0 ) print "【内网IP:"$1",MAC:"$2",名称:"$3"】  "}' >> /tmp/var/newhostname.txt
    touch /etc/storage/hostname.txt
    [ ! -s /etc/storage/hostname.txt ] && echo "接入设备名称" > /etc/storage/hostname.txt
    awk 'NR==FNR{a[$0]++} NR>FNR&&a[$0]' /etc/storage/hostname.txt /tmp/var/newhostname.txt > /tmp/var/newhostname相同行.txt
    awk 'NR==FNR{a[$0]++} NR>FNR&&!a[$0]' /tmp/var/newhostname相同行.txt /tmp/var/newhostname.txt > /tmp/var/newhostname不重复.txt
    if [ -s "/tmp/var/newhostname不重复.txt" ] ; then
        content=`cat /tmp/var/newhostname不重复.txt | grep -v "^$"`
        
        # Bark 推送
        body="新设备加入:${content}"
        curl -L -s -X POST -d "title=${bark_title}" -d "body=${body}" -d "group=${bark_group}" -d "icon=${bark_icon}" "${bark_url}" &
        
        logger -t "【Bark推送】" "PDCN新设备加入:${content}"
        cat /tmp/var/newhostname不重复.txt | grep -v "^$" >> /etc/storage/hostname.txt
    fi
fi

# 【功能3:设备上、下线提醒】
if [ "$serverchan_notify_4" = "1" ] ; then
    touch /tmp/var/newhostname.txt
    echo "接入设备名称" > /tmp/var/newhostname.txt
    cat /tmp/static_ip.inf | grep -v "^$" | awk -F "," '{ if ( $6 == 0 ) print "【内网IP:"$1",MAC:"$2",名称:"$3"】  "}' >> /tmp/var/newhostname.txt
    touch /etc/storage/hostname_上线.txt
    [ ! -s /etc/storage/hostname_上线.txt ] && echo "接入设备名称" > /etc/storage/hostname_上线.txt
    
    # 上线
    awk 'NR==FNR{a[$0]++} NR>FNR&&a[$0]' /etc/storage/hostname_上线.txt /tmp/var/newhostname.txt > /tmp/var/newhostname相同行_上线.txt
    awk 'NR==FNR{a[$0]++} NR>FNR&&!a[$0]' /tmp/var/newhostname相同行_上线.txt /tmp/var/newhostname.txt > /tmp/var/newhostname不重复_上线.txt
    if [ -s "/tmp/var/newhostname不重复_上线.txt" ] ; then
        content=`cat /tmp/var/newhostname不重复_上线.txt | grep -v "^$"`
        
        # Bark 推送
        body="设备【上线】Online:${content}"
        curl -L -s -X POST -d "title=${bark_title}" -d "body=${body}" -d "group=${bark_group}" -d "icon=${bark_icon}" "${bark_url}" &
        
        logger -t "【Bark推送】" "PDCN设备【上线】:${content}"
        cat /tmp/var/newhostname不重复_上线.txt | grep -v "^$" >> /etc/storage/hostname_上线.txt
    fi
    # 下线
    awk 'NR==FNR{a[$0]++} NR>FNR&&!a[$0]' /tmp/var/newhostname.txt /etc/storage/hostname_上线.txt > /tmp/var/newhostname不重复_下线.txt
    if [ -s "/tmp/var/newhostname不重复_下线.txt" ] ; then
        content=`cat /tmp/var/newhostname不重复_下线.txt | grep -v "^$"`
        
        # Bark 推送
        body="设备【下线】Offline:${content}"
        curl -L -s -X POST -d "title=${bark_title}" -d "body=${body}" -d "group=${bark_group}" -d "icon=${bark_icon}" "${bark_url}" &
        
        logger -t "【Bark推送】" "PDCN设备【下线】:${content}"
        cat /tmp/var/newhostname.txt | grep -v "^$" > /etc/storage/hostname_上线.txt
    fi
fi

# 【功能4:固件更新提醒】
if [ "$serverchan_notify_3" = "1" ] && [ "$resub" = "1" ] ; then
    [ ! -f /tmp/var/osub ] && echo -n `nvram get firmver_sub` > /tmp/var/osub
    rm -f /tmp/var/nsub
    wgetcurl.sh "/tmp/var/nsub" "$hiboyfile/osub" "$hiboyfile2/osub"
    [[ "$(cat /tmp/var/nsub | wc -c)" -ge 20 ]] && echo "" /tmp/var/nsub
    [ ! -z "$(cat /tmp/var/nsub | grep '<' | grep '>')" ] && echo "" > /tmp/var/nsub
    if [ "$(cat /tmp/var/osub |head -n1)"x != "$(cat /tmp/var/nsub |head -n1)"x ] && [ -f /tmp/var/nsub ] ; then
        echo -n `nvram get firmver_sub` > /tmp/var/osub
        content="新的固件: `cat /tmp/var/nsub | grep -v "^$"` ,目前旧固件: `cat /tmp/var/osub | grep -v "^$"` "
        
        # Bark 推送
        body="固件更新提醒:${content}"
        curl -L -s -X POST -d "title=${bark_title}" -d "body=${body}" -d "group=${bark_group}" -d "icon=${bark_icon}" "${bark_url}" &
        
        logger -t "【Bark推送】" "固件 新的更新:${content}"
        echo -n `cat /tmp/var/nsub | grep -v "^$"` > /tmp/var/osub
    fi
fi
    resub=`expr $resub + 1`
    [ "$resub" -gt 360 ] && resub=1
else
echo "Internet down 互联网断线"
resub=1
fi
sleep 60
continue
done

如何食用?

  1. 获取代码: 复制上方的完整代码。如果是你自己搭建的 Bark Server,或者想换个通知图标,只需修改开头 ========= Bark 自定义配置区 ========= 里面的内容即可。
  2. 替换脚本: 登录你的老毛子路由器后台。依次展开左侧的 高级设置 -> 自定义设置 -> 脚本
  3. 定位原有位置: 找到原本用来存放 Server酱 脚本的地方(通常是 运行 Router 启动后 或者单独的微信推送脚本区),将里面的老代码全选删除,粘贴我们新的脚本。
  4. 保存应用: 点击页面最下方的 应用本页面设置。由于所有的 Bark 链接和配置都已经直接写死在代码顶部了,你不需要再去路由器后台专门填 Server酱 Key 的地方填任何东西。

大功告成!现在,不论是宿舍里新连接了一台手机,还是路由器重新拨号换了 IP,你的 iPhone 都会“滴”的一声,弹出一个带着专属图标的 Bark 消息。完全免费,极速触达!

最后修改:2026 年 03 月 19 日 06 : 05 PM

发表评论