Linux 之 crontab 【配置定时任务】

[复制链接]
发表于 2026-10-5 19:10:34 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×

定时任务这块,最常见的坑不是「不会写表达式」,而是「脚本手动执行没问题,交给 crontab 就失败」。本文从一个真实需求切入:每小时进入 /home/threeinf 目录执行 sh run.sh restart,把配置过程、验证方法和那个必踩的环境变量坑一次讲透。

一、场景

要求:每小时定时到 /home/threeinf 目录下,执行 sh run.sh restart。

注意「进入目录」这个动作本身是要写进 crontab 的——cron 的工作目录是用户的家目录(通常是 ~),不会自动切到脚本所在目录。如果脚本里写的是相对路径,不切目录就会找不到文件,这是很多人配完没反应的第一个原因。

二、配置过程

2.1 编辑定时任务列表

crontab -e

这个命令相当于编辑当前用户的 crontab 文件,第一次执行会让你选一个编辑器,选 vi 之后就是熟悉的 vi 界面。跟常规 vi 操作一样:按 i 进入编辑,改完按 Esc 再输入 :wq 回车保存退出。

2.2 添加这条任务

0 * * * * cd /home/threeinf && sh run.sh restart

五个星号位置的含义依次是:分、时、日、月、周。这条的意思就是「每小时的第 0 分钟,进入 threeinf 目录再执行重启」。用 && 连接可以保证前面的 cd 成功才执行后面的脚本,比单独写两行更稳妥。

2.3 查看已有任务

crontab -l

能列出刚才加的那条,说明写入成功。

2.4 重启定时服务

systemctl restart crond.service

注意服务名:CentOS / RHEL 系列是 crond,Ubuntu / Debian 系列是 cron。用错服务名会提示 Unit not found。

2.5 看执行日志日志

tail -f /var/log/cron

有输出结果就说明任务真的被触发了。CentOS 7+ 的 cron 日志日志也可能在 /var/log/cron,如果没内容,检查 /etc/rsyslog.d/ 下 cron 相关的日志日志规则是否启用。

三、核心坑:脚本手动执行成功,crontab 执行失败

这是最让人困惑的现象:同一个脚本,你登上去手工跑 sh run.sh restart 一切正常,丢给 crontab 就报错或者没反应。

3.1 原因

crontab 执行任务时不会默认从用户的 profile 文件里读取环境变量。我们登录 Linux 时,/etc/profile、~/.bash_profile、~/.bashrc 这些配置文件会被自动执行一遍,里面定义的 PATH、JAVA_HOME、LD_LIBRARY_PATH 等变量也就随之生效。但 cron 启动进程时走的是另一条路径,没有登录 shell 的概念,上述文件不会被执行,所以脚本里用到的命令路径、环境变量全都是空的。

结果就是:脚本里写 java -version 找不到命令,或者 $JAVA_HOME 展开为空导致启动失败——而你手工执行时因为 profile 生效,一切正常。

3.2 解决办法

在 shell 脚本开头(#!/bin/sh 那一行之后)显式 source 一次配置文件:

#!/bin/bash
source /etc/profile
source ~/.bash_profile

这两行加上去,脚本在 cron 环境里就能拿到和用户登录时一样的变量。如果脚本路径里有中文或者有特殊字符,记得在开头加 export LANG=zh_CN.UTF-8,避免编码问题。

另一种做法是在 crontab 里直接写全路径,比如 0 * * * * cd /home/threeinf && /usr/bin/sh /home/threeinf/run.sh restart,把所有依赖的命令都用绝对路径指定。两种方式选一个,别混用——混用会让排查变得非常绕。

四、表达式与写法上的几个细节

  • 执行间隔:*/5 * * * * 是每 5 分钟,0 * * * * 是整点,30 2 * * * 是每天凌晨 2 点半。
  • 输出重定向:cron 默认会把任务的输出发到用户邮箱,脚本里有大量输出时会攒一堆邮件。不想要的话在末尾加 > /dev/null 2>&1;反过来,出故障时把输出重定向到文件更好排查:> /tmp/run.log 2>&1。
  • 用户区分:crontab -e 编辑的是当前用户的任务;要给系统级任务写 /etc/crontab,那里多一个用户字段。别把用户任务写错地方。
  • 秒级任务:cron 最小粒度是分钟,需要秒级只能用脚本循环或专用调度器。

五、排查清单

  1. crontab -l 确认任务在。
  2. tail -f /var/log/cron 看任务有没有被触发、触发时间对不对。
  3. 把脚本的 stdout/stderr 重定向到日志文件,看真实报错。
  4. 检查脚本执行权限:chmod +x run.sh,或者像本文这样直接写 sh run.sh 绕过执行位。
  5. 检查执行用户是否有目录读写权限,cron 通常不以 root 身份跑。

把这几步走顺,定时任务基本就不会出意外。关键是记住一句话:cron 里没有登录 shell,所有环境变量都得自己补上。

qidao123.com企服评测-应用市场 编辑提示

回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表