#!/data/data/com.termux/files/usr/bin/bash # audit_recent_send.sh — 微信发送「送达核验」自检:报告最近几次发送尝试的成败签名 # # 用法: # bash audit_recent_send.sh [窗口分钟数] # 默认 30 # # 输出: 每个覆盖窗口的 verbose 日志段(文件名=段起始时间)+ 五类签名计数 + 带时间戳的明细。 # 判定(详见 SKILL.md 真判据表): # oj_DONE>0 或 CDN_submit>0 ⇒ 真发出(再按 to= 逐目标核) # SEND_IMAGE_INTERNAL>0 且 oj_DONE=0 ⇒ 没发出去(含 failed>0 的情况)⇒ 用同一脚本重试一次 # 全 0 ⇒ 本段没有发送;换更早的段(日志 ~4MB 轮转,见 SKILL.md) # # ⚠️ 本脚本只【打印证据】,不做最终判定。 # ⚠️ 别把本脚本的逻辑改写成 terminal 里的一行命令(python3 -c / 嵌套 $() 在无人值守环境会被审批门卡死或直接 BLOCKED)。 set -u MIN="${1:-30}" LOGDIR=/data/adb/lspd/log echo "=== audit_recent_send: $(date '+%Y-%m-%d %H:%M:%S') window=${MIN}min ===" FILES=$(su -c "ls -t $LOGDIR/verbose_*.log" 2>/dev/null | tr -d '\r' | head -3) if [ -z "$FILES" ]; then echo "NO_LOG: 取不到 verbose_*.log(su 失败 / 目录变了?)" echo " 手动确认: su -c 'ls -lt $LOGDIR | head'" exit 3 fi for L in $FILES; do MT=$(su -c "stat -c %y $L" 2>/dev/null | tr -d '\r') SZ=$(su -c "stat -c %s $L" 2>/dev/null | tr -d '\r') echo "--- $(basename "$L") size=${SZ}B mtime=${MT}" N_SEND=$(su -c "grep -a -c 'SEND_IMAGE_INTERNAL' $L" 2>/dev/null | tr -d '\r') N_FAIL=$(su -c "grep -a -c 'SEND_IMAGE_INTERNAL failed' $L" 2>/dev/null | tr -d '\r') N_DONE=$(su -c "grep -a -c 'oj() DONE' $L" 2>/dev/null | tr -d '\r') N_CDN=$(su -c "grep -a -c 'CDN submit DONE' $L" 2>/dev/null | tr -d '\r') N_DB=$(su -c "grep -a -c 'isSend=1 status=1' $L" 2>/dev/null | tr -d '\r') echo " SEND_IMAGE_INTERNAL=$N_SEND failed=$N_FAIL oj_DONE=$N_DONE CDN_submit=$N_CDN isSend1=$N_DB" echo " (计数=整段 ~40min,可能含上一轮;以明细行的时间戳与 to= 为准)" if [ "${N_SEND:-0}" != "0" ] || [ "${N_DONE:-0}" != "0" ]; then echo " --- 明细(尾部 12 行)---" su -c "awk '/SEND_IMAGE_INTERNAL|sendImageViaAPI|oj\(\) DONE|CDN submit DONE/{print substr(\$0,2,24) \" | \" substr(\$0,index(\$0,\"WeChatHook\")+11,120)}' $L" 2>/dev/null | tr -d '\r' | tail -12 echo " --- 失败原文(尾部 3 行,若有)---" su -c "awk '/failed/{print substr(\$0,2,24) \" | \" substr(\$0,index(\$0,\"WeChatHook\")+11,160)}' $L" 2>/dev/null | tr -d '\r' | tail -3 fi done echo echo "=== 结论模板 ===" echo " failed>0 且 oj_DONE=0 ⇒ 没发出去:用【同一发送脚本、同一图片】立刻重跑一次(新进程⇒新暂存名);" echo " 重试不会让对方收到两张(失败那次没上 CDN);重试仍失败才按故障上报。" echo " 段内全 0 ⇒ 本段不覆盖发送时刻,去找 mtime ≈ 发送时刻的那一份 verbose 日志。"