LinuxShell任务调度方案_周期执行设计说明【指导】

11次阅读

crontab -e 编辑后不生效需检查三处:用户与系统crond服务匹配、crond服务是否运行、脚本中命令是否使用绝对路径;还需注意环境变量加载、日志重定向、高频任务处理及锁机制。

LinuxShell任务调度方案_周期执行设计说明【指导】

crontab -e 编辑后不生效?检查这三处

linux 下用 crontab -e 添加定时任务后没运行,大概率不是语法写错,而是环境、权限或路径问题。

  • 用户 crontab 和系统 crond 服务必须匹配:普通用户用 crontab -e,root 用 sudo crontab -e;二者配置不互通
  • crond 服务必须运行:systemctl status crondebian/ubuntu)或 systemctl status crond(RHEL/centos),未激活则 systemctl start cron
  • 脚本中所有命令必须用绝对路径:/usr/bin/python3 而非 python3/home/user/script.sh 而非 ./script.sh;crond 默认 $PATH 极简(通常只有 /usr/bin:/bin

如何让 cron 正确加载当前 shell 环境变量

cron 不读取 ~/.bashrc/etc/profile,所以你在终端能跑通的命令,在 cron 里常因缺 $HOME$PYTHONPATH 或自定义 alias 失败。

  • 最稳妥方式:在脚本开头显式 source 环境文件,例如:
    #!/bin/bash source /home/user/.bashrc export PATH="/home/user/.local/bin:$PATH" python3 /home/user/job.py
  • 避免在 crontab 行内直接写 source:cron 解析器不支持该语法,会报 bad command
  • 临时调试可加日志:* * * * * /home/user/test.sh >> /tmp/cron.log 2>&1,然后 tail -f /tmp/cron.log 查看实际执行时的环境输出

分钟级高频任务(如每 10 秒跑一次)不能只靠 * * * * *

* 最小粒度是 1 分钟,无法实现秒级调度。硬凑 * * * * * sleep 10; cmd 会导致每次启动时间漂移,且并发风险高。

  • 真需要 sub-minute 频率,改用后台循环 + sleep
    #!/bin/bash while true; do   /home/user/check.sh   sleep 10 done

    ,再用 nohup ./loop.sh & 启动,并配合 systemd service 管理生命周期

  • 若仍想走 cron,可用多个错开的条目模拟(如 */10 * * * * cmd + */10 * * * * sleep 10; cmd),但不可靠,仅限临时验证
  • 注意系统负载:高频任务务必在脚本内加锁(如用 flock),否则可能多个实例同时写同一文件或重复发请求

日志和错误捕获必须显式重定向,别信默认行为

cron 默认把 stdout/stderr 发邮件给用户(需本地 MTA 配置),多数服务器根本没配 sendmail,结果就是“静默失败”。

  • 每行 cron 必须带重定向:0 2 * * * /home/user/backup.sh >> /var/log/backup.log 2>&1
  • 不要只写 2>&1:它只重定向 stderr 到当前 stdout,而 stdout 默认是空设备;必须先指定 stdout 输出位置,2>&1 才有意义
  • 日志轮转建议用 logrotate 配合,或脚本内判断文件大小后 mv backup.log backup.log.$(date +%s)

cron 的可靠性不取决于你写得多漂亮,而在于你是否提前堵住了环境差异、路径歧义和输出黑洞这几个口子。真正上线前,至少手动跑一遍脚本、查一遍 journalctl -u cron -n 50、翻一遍目标日志文件的权限和内容。

text=ZqhQzanResources