sh#!/bin/sh
STATE="/root/.traffic_state"
LOG_FILE="/root/traffic_monitor.log"
LIMIT_GB=10
LIMIT=$((LIMIT_GB * 1024 * 1024 * 1024))
IFACE=$(ip route 2>/dev/null | grep default | awk '{print $5}' | head -1)
[ -z "$IFACE" ] && IFACE="eth0"
# 获取当前网卡总字节数 (接收 + 发送)
BYTES=$(awk -v iface="$IFACE" 'NR>1{split($1,a,":"); if(a[1]==iface){print $2+$10; exit}}' /proc/net/dev)
[ -z "$BYTES" ] && exit 0
TODAY=$(date +%Y-%m-%d)
# 初始化变量
ACC_BYTES=0 # 今日累计流量
LAST_KERNEL=0 # 上次记录的网卡内核计数值
LAST_DATE=""
# 读取状态文件
if [ -f "$STATE" ]; then
ACC_BYTES=$(grep "^acc_bytes=" "$STATE" 2>/dev/null | cut -d= -f2)
LAST_KERNEL=$(grep "^last_kernel=" "$STATE" 2>/dev/null | cut -d= -f2)
LAST_DATE=$(grep "^last_date=" "$STATE" 2>/dev/null | cut -d= -f2)
fi
# 初始化保护 (如果是第一次运行或状态文件缺失)
[ -z "$ACC_BYTES" ] && ACC_BYTES=0
[ -z "$LAST_KERNEL" ] && LAST_KERNEL=$BYTES
# 1. 日期变更:重置累计流量
if [ "$TODAY" != "$LAST_DATE" ]; then
ACC_BYTES=0
LAST_KERNEL=$BYTES
fi
# 2. 计算本次增量
DELTA=$((BYTES - LAST_KERNEL))
# 3. 检测网卡重启/计数器归零 (增量变负数)
if [ "$DELTA" -lt 0 ] 2>/dev/null; then
# 网卡重置了,增量视为 0,但保留之前的 ACC_BYTES 不清零
DELTA=0
# 记录重置事件到日志,方便排查
echo "$(date '+%Y-%m-%d %H:%M:%S') - INFO: Network counter reset detected. Keeping accumulated traffic." >> "$LOG_FILE"
fi
# 4. 累加到今日总用量
ACC_BYTES=$((ACC_BYTES + DELTA))
# 更新 LAST_KERNEL 为当前值,供下次计算增量
LAST_KERNEL=$BYTES
# 格式化显示 (GB)
USED_GB=$(awk "BEGIN {printf \"%.2f\", $ACC_BYTES/1024/1024/1024}")
echo "Today Total: ${USED_GB} GB / ${LIMIT_GB} GB"
# 记录日志 (显示累计用量)
echo "$(date '+%Y-%m-%d %H:%M:%S') - Total Usage: ${USED_GB}GB / ${LIMIT_GB}GB" >> "$LOG_FILE"
# 5. 判断是否超限
if [ "$ACC_BYTES" -gt "$LIMIT" ]; then
echo "!!! 流量超限,执行关机 !!!"
echo "$(date '+%Y-%m-%d %H:%M:%S') - WARNING: LIMIT EXCEEDED! SHUTTING DOWN!" >> "$LOG_FILE"
# 保存状态 (虽然马上要关机,但保持习惯)
echo "acc_bytes=$ACC_BYTES" > "$STATE"
echo "last_kernel=$LAST_KERNEL" >> "$STATE"
echo "last_date=$TODAY" >> "$STATE"
chmod 600 "$STATE"
poweroff -f
fi
# 6. 保存状态
echo "acc_bytes=$ACC_BYTES" > "$STATE"
echo "last_kernel=$LAST_KERNEL" >> "$STATE"
echo "last_date=$TODAY" >> "$STATE"
chmod 600 "$STATE"
赋予执行权限
chmod 700 /root/traffic_kill.sh
状态文件重置(改阈值的事后最好重置一下,然后再手动测试)
rm -f /root/.traffic_state
手动测试
/root/traffic_kill.sh
查看生成的日志
cat /root/traffic_monitor.log
修改安装源为阿里云
sed -i 's|https\?://[^/]*/alpine/|https://mirrors.aliyun.com/alpine/|g' /etc/apk/repositories sed -i 's|/v[0-9.]*/|/latest-stable/|g' /etc/apk/repositories
安装并配置 cron(Alpine Linux)
# 安装 cron apk add --no-cache openrc dcron # 设置开机自启 rc-update add dcron # 启动 cron 服务 rc-service dcron start
添加定时任务
# 使用 crontab -e 编辑(推荐) crontab -e # 添加以下内容: @reboot /root/traffic_kill.sh */1 * * * * /root/traffic_kill.sh
注意
1.按 i 键进入插入模式
2.输入以下两行(确保每行一个任务):
@reboot /root/traffic_kill.sh
*/1 * * * * /root/traffic_kill.sh
3.按 ESC 键退出插入模式
4.输入
保存并退出验证设置
# 验证 cron 服务状态 rc-service dcron status # 查看开机自启 rc-update show | grep dcron # 查看 crontab 内容 crontab -l
等待定时查看状态文件验证定时任务是否生效
cat /root/.traffic_state
返回的状态信息内容解读
acc_bytes=107857179 #单日累计字节数
last_kernel=1364664 #上次统计的字节数
last_date=2026-03-12 #上次统计的时间
本文作者:cokey
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 许可协议。转载请注明出处!