xiaowei-system/skills/devops/devops-umbrella/references/cron-wrapper-script-debug.md

2.6 KiB
Raw Blame History

Cron Wrapper 脚本诊断与修复2026-07-17 实测)

症状

Script not found: /home/muc/.hermes/scripts/skill-manager.py scan
Script not found: /home/muc/.hermes/scripts/optimizer.py report

明明文件存在,但 cron 报找不到。

根因

hermes cron 的 no_agent 模式把 script 字段当作完整文件名处理——带空格的字符串不会被解析为"脚本名 + 参数",而是当作单个带空格的文件名。

# cron 定义的 script 字段:
script: "skill-manager.py scan"      # ❌ 找 "skill-manager.py scan" 这个文件(不存在)
script: "skill-manager.py"           # ❌ 如果 scan 是参数,也找不到

诊断脚本

# 检查所有 no_agent cron 的 script 字段是否包含空格
hermes cron list 2>/dev/null | grep -B2 "no-agent" | grep "Script:"
# 或者直接查 wrapper 脚本内容
for f in ~/.hermes/scripts/*.sh; do
  content=$(cat "$f" 2>/dev/null)
  # 找有问题的模式python3 xxx.py 后面直接跟命令,中间没有换行
  if echo "$content" | grep -qE "python3.*\.py [a-z]"; then
    echo "❌ $f 有问题(缺换行)"
  fi
done

正确写法

#!/bin/bash
python3 ~/.hermes/scripts/skill-manager.py scan
#                   ↑ 换行,不是空格

#!/bin/bash
cd ~/.hermes/scripts && python3 optimizer.py report
#                   ↑ 换行

批量检测

# 查 cron job 配置中的问题 script
import json

with open(os.path.expanduser("~/.hermes/cron/jobs.json")) as f:
    jobs = json.load(f)

issues = []
for job in jobs.get("jobs", []):
    script = job.get("script", "")
    mode = job.get("no_agent", False)
    if mode and " " in script and not script.endswith(".sh"):
        issues.append(f"  ❌ {job['name']} ({job['id']}): script='{script}'")

if issues:
    print("检测到 cron wrapper 问题:")
    for i in issues: print(i)
else:
    print("✅ 无 cron wrapper 问题")

今天修复的受影响 cron4个

Cron ID 名称 原因
c143d2afe640 技能健康扫描 skill-manager-scan.sh 缺换行符
1e19f7429ddf 自我优化报告 optimizer-report.sh 同上
b192a7cec1b5 主动学习自检报告 proactive-learning-report.sh 同上
6061a782b772 股票投研周学习 stock_learning.sh 不存在

预防

新增任何 cron job 时,如果 script 是 Python/脚本带参数:

  1. 先写 xxx.sh wrapper#!/bin/bash + 单行 python3 ...
  2. 再用 wrapper 路径作为 script 字段值
  3. 用上面的诊断脚本验证

hermes cron 的 no_agent 模式不支持参数展开,任何参数都必须 bake 进 wrapper 脚本里。