You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决Crontab无法以Root身份每5分钟执行Shell脚本的问题?

Crontab定时执行Shell脚本失败修复

一、必须修改的几个点

  • 修正定时表达式:你写的5/5 * * * *是错误的,要实现每5分钟执行一次,应该写成*/5 * * * *。5/5的逻辑是“每小时第5分钟开始,每5分钟跑一次”,不符合需求;*/5才是任意时间点每5分钟执行。
  • 使用脚本绝对路径:crontab的默认工作目录是root的家目录/root,./var/update-dns/updateDNS.sh这种相对路径会找不到文件,直接改成绝对路径/var/update-dns/updateDNS.sh。
  • 给脚本添加执行权限:执行这条命令赋予脚本可执行权限:
    chmod +x /var/update-dns/updateDNS.sh
    
  • 修复脚本逻辑与细节:
    1. 脚本开头加上#!/bin/bash,明确指定bash解释器;
    2. 脚本里if [ $LOGFILE = "" ] ; then这个判断永远不会触发,因为LOGFILE已经被赋值,应改成判断日志文件是否存在:if [ ! -f "$LOGFILE" ] ; then;
    3. 因为是root身份执行crontab,脚本里的sudo可以直接删除,避免冗余权限调用;
    4. crontab的PATH环境变量范围很窄,可能找不到host、curl、ufw等命令,先查它们的绝对路径:
      which host curl ufw
      
      把脚本里的对应命令替换成绝对路径版本(比如/usr/bin/host、/usr/bin/curl、/usr/sbin/ufw);
    5. 建议给输出加上时间戳并追加到日志,方便排查问题,比如把echo内容改成echo "$(date): 内容" >> $LOGFILE。

修正后的脚本参考:

#!/bin/bash
/usr/bin/curl http://localhost/external_ip.php
HOSTNAME=pi.marvinkleinmusic.de
LOGFILE=/var/update-dns/log.txt

Current_IP=$(/usr/bin/host $HOSTNAME | cut -f4 -d' ')

if [ ! -f "$LOGFILE" ] ; then
  /usr/sbin/ufw allow from $Current_IP
  echo "$(date): 初始化IP规则,当前IP: $Current_IP" > $LOGFILE
else
  Old_IP=$(cat $LOGFILE)

  if [ "$Current_IP" = "$Old_IP" ] ; then
    echo "$(date): IP地址未变化" >> $LOGFILE
  else
    /usr/sbin/ufw delete allow from $Old_IP
    /usr/sbin/ufw allow from $Current_IP
    
    echo $Current_IP > $LOGFILE
    echo "$(date): 防火墙规则已更新,旧IP: $Old_IP,新IP: $Current_IP" >> $LOGFILE
  fi
fi
  • 修正后的crontab条目:编辑root的crontab(sudo crontab -e),添加这条规则:
    */5 * * * * /var/update-dns/updateDNS.sh >> /var/update-dns/cron.log 2>&1
    
    末尾的>> /var/update-dns/cron.log 2>&1是把脚本的输出和错误信息都重定向到日志文件,方便排查问题。

二、关于Crontab启用的问题

树莓派默认已经启用了cron服务,不确定的话可以查状态:

sudo systemctl status cron

如果显示active (running)就没问题;要是没启动,执行以下两条命令:

sudo systemctl start cron
sudo systemctl enable cron

三、如何查看任务是否执行?

  1. 查看cron系统日志:cron的执行记录存在/var/log/syslog里,用grep过滤查看:
    grep CRON /var/log/syslog
    
    如果任务执行了,会看到类似这样的记录:
    Jun 10 14:05:00 raspberrypi CRON[12345]: (root) CMD (/var/update-dns/updateDNS.sh >> /var/update-dns/cron.log 2>&1)
    
  2. 查看脚本输出日志:直接查看你设置的/var/update-dns/cron.log文件,里面会有脚本运行的输出和错误信息:
    cat /var/update-dns/cron.log
    
  3. 检查日志文件修改时间:查看脚本生成的/var/update-dns/log.txt的更新时间,判断是否每5分钟更新一次:
    ls -l /var/update-dns/log.txt
    

内容的提问来源于stack exchange,提问作者Marvin Klein

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 09:35:22