#!/bin/bash PATH=/usr/sbin:/usr/bin:/sbin:/bin # 流量阈值(单位 GB),由 kejilion.sh 菜单写入 threshold_gb=110 if [ ! -r /proc/net/dev ]; then echo "无法读取 /proc/net/dev,跳过本次流量检查。" >&2 exit 1 fi # 统计外部网卡的累计收发流量(排除回环和常见容器/隧道接口) output=$(awk 'BEGIN { rx_total = 0; tx_total = 0 } NR > 2 { idx = index($0, ":"); if (idx == 0) next; iface = substr($0, 1, idx - 1); gsub(/[ \t]/, "", iface); if (iface == "lo" || iface ~ /^(docker|veth|br-|virbr|tun|tap|wg|tailscale|zt)/) next; split(substr($0, idx + 1), f, " "); rx_total += f[1]; tx_total += f[9]; } END { printf("%.0f %.0f", rx_total, tx_total); }' /proc/net/dev) # 获取接收和发送的流量数据(单位:字节) rx=$(echo "$output" | awk '{print $1}') tx=$(echo "$output" | awk '{print $2}') # 取值异常时直接退出,避免把空值带进整数比较导致误判。 # 必须分开校验:拼接后 rx 为空、tx 非空的情况会被误判为合法。 case "$rx" in ''|*[!0-9]*) echo "流量统计结果异常,跳过本次检查。" >&2 exit 1 ;; esac case "$tx" in ''|*[!0-9]*) echo "流量统计结果异常,跳过本次检查。" >&2 exit 1 ;; esac # 显示当前流量使用情况 awk -v rx="$rx" -v tx="$tx" 'BEGIN { printf("当前接收流量: %.2f GB\n当前发送流量: %.2f GB\n", rx / 1073741824, tx / 1073741824); }' # 配置可能被手动修改,执行关机前再次校验阈值 case "$threshold_gb" in ''|*[!0-9]*) echo "流量阈值配置不合法: ${threshold_gb}" >&2 exit 1 ;; esac # 用整数比较而非匹配字面量 0,否则 00/000 会漏网并让阈值变成 0(每分钟关机) if [ "$threshold_gb" -le 0 ]; then echo "流量阈值必须大于 0: ${threshold_gb}" >&2 exit 1 fi # 任一方向达到阈值即触发。主流 VPS(Vultr/DO/Linode/Hetzner)只计出站, # 按单向最大值判断更贴近实际配额,也与旧版行为保持一致。 if awk -v rx="$rx" -v tx="$tx" -v threshold_gb="$threshold_gb" 'BEGIN { threshold = threshold_gb * 1073741824; exit !(rx >= threshold || tx >= threshold); }'; then echo "单向流量已达到 ${threshold_gb}GB,正在关闭服务器..." if command -v systemctl >/dev/null 2>&1 && systemctl poweroff; then exit 0 fi if command -v shutdown >/dev/null 2>&1 && shutdown -h now; then exit 0 fi echo "提交关机请求失败,未找到可用命令或命令执行失败。" >&2 exit 1 else echo "当前单向流量未达到 ${threshold_gb}GB,继续监视..." fi