cron
全局配置
/etc/crontab
文件包括环境变量与任务的配置:
SHELL=/bin/bash PATH=/sbin:/bin:/usr/sbin:/usr/bin MAILTO=""HOME=/ # run-parts 51 * * * * root run-parts /etc/cron.hourly 24 7 * * * root run-parts /etc/cron.daily 22 4 * * 0 root run-parts /etc/cron.weekly 42 4 1 * * root run-parts /etc/cron.monthly
-
第一行
SHELL
变量指定了系统要使用哪个shell,这里是bash
-
第二行
PATH
变量指定了系统执行命令的路径 -
第三行
MAILTO
变量指定了crond的任务执行信息将通过电子邮件发送给root用户, 如果MAILTO
变量的值为空,则表示不发送任务执行信息给用户, -
第四行的
HOME
变量指定了在执行命令或者脚本时使用的主目录。 - 第六至九行定义了定时任务
-
*
:代表所有可能的值,例如month字段如果是星号, 则表示在满足其它字段的制约条件后每月都执行该命令操作。 -
,
:可以用逗号隔开的值指定一个列表范围,例如,1,2,5,7,8,9
-
-
:可以用整数之间的中杠表示一个整数范围,例如2-6
表示2,3,4,5,6
-
/
:可以用正斜线指定时间的间隔频率,例如0-23/2
表示每两小时执行一次。 同时正斜线可以和星号一起使用,例如*/10
,如果用在minute
字段,表示每十分钟执行一次。
所有用户定义的crontab文件都被保存在/var/spool/cron
目录中。
其文件名与用户名一致。
权限配置:
-
/etc/cron.deny
:该文件中所列用户不允许使用crontab命令 -
/etc/cron.allow
:该文件中所列用户允许使用crontab命令 -
/var/spool/cron/
:所有用户crontab文件存放的目录,以用户名命名
需要注意的问题
今天遇见一个问题,crontab的定时任务不能自动执行,但是手动执行脚本一直能成功。 查到最后,发现是脚本里用了系统的环境变量。下面开始解释:
1.crontab与环境变量
不要假定cron知道所需要的特殊环境,它其实并不知道。 所以你要保证在shelll脚本中提供所有必要的路径和环境变量, 除了一些自动设置的全局变量。所以注意如下3点:
1)脚本中涉及文件路径时写全局路径;
2)脚本执行要用到java或其他环境变量时,通过source命令引入环境变量,如:
cat start_cbp.sh #!/bin/sh source /etc/profile export RUN_CONF=/home/d139/conf/platform/cbp/cbp_jboss.conf /usr/local/jboss-4.0.5/bin/run.sh -c mev &
3)当手动执行脚本OK,但是crontab死活不执行时。这时必须大胆怀疑是环境变量惹的祸, 并可以尝试在crontab中直接引入环境变量解决问题。如:
0 * * * * . /etc/profile;/bin/sh /var/www/java/audit_no_count/bin/restart_audit.sh
2.其他应该注意的问题
1)新创建的cron job,不会马上执行,至少要过2分钟才执行。如果重启cron则马上执行。
2)每条 JOB 执行完毕之后,系统会自动将输出发送邮件给当前系统用户。日积月累,
非常的多,甚至会撑爆整个系统。所以每条 JOB 命令后面进行重定向处理是非常必要的:
>/dev/null 2>&1
。前提是对 Job 中的命令需要正常输出已经作了一定的处理,
比如追加到某个特定日志文件。
3)当crontab突然失效时,可以尝试/etc/init.d/crond restart
解决问题。
或者查看日志看某个job有没有执行/报错tail -f /var/log/cron
。
4)千万别乱运行crontab -r
。它从Crontab目录(/var/spool/cron)中删除用户的Crontab文件。
删除了该用户的所有crontab都没了。
5)在crontab中%
是有特殊含义的,表示换行的意思。如果要用的话必须进行转义\%
,
如经常用的date '+%Y%m%d'
在crontab里是不会执行的,应该换成date '+\%Y\%m\%d'
。
3.crontab中的输出配置
crontab中经常配置运行脚本输出为:>/dev/null 2>&1
,来避免crontab运行中有内容输出。
4.登录对环境变量与配置的影响
Linux 中定时任务不生效的问题屡见不鲜, 本质原因是: 登录式 shell & 非登录式 shell.
登录式 shell 有:
-
su - <username>
-
Login: username / password
非登录式 shell
-
su <username>
- 图形界面
- 脚本执行
Bash 配置文件
全局配置文件
-
/etc/profile
-
/etc/profile.d/*.sh
-
/etc/bashrc
用户配置文件
-
~/.bash_profile
-
~/.bashrc
profile 类文件主要用途
- 设定环境变量
- 运行命令和脚本
bashrc 类文件主要用途
- 设定本地变量
- 定义命令别名
shell 读取配置文件顺序
登录式 shell
/etc/profile
--> /etc/profile.d
--> ~/.bash_profile
--> ~/.bashrc
--> /etc/bashrc
非登录式 shell
~/.bashrc
--> /etc/bashrc
--> /etc/profile.d/*.sh
由以上信息可知, 因为定时任务是「非登录式 shell」,
故而很多环境变量不会被加载, 其中包括PATH
.
我自己写定时任务脚本的时候, 会在脚本的开头写:
#!/bin/sh export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/usr/local/zookeeper/bin:/root/bin
5.PAM权限问题
首先确定脚本可以手动执行,然后查看定时任务的日志/var/log/cron
,
发现日志中报错如下(程序名) FAILED to authorize user with PAM (Module is unknown)
解决方法:修改/etc/pam.d/crond
,把把所有required改成sufficient,这个对非root用户管用
account sufficient pam_access.so account include password-auth session sufficient pam_loginuid.so session include password-auth auth include password-auth
配置修改后,使用/etc/init.d/crond restart
重启crontab使之生效(Centos7使用命令systemctl restart crond重启)
这样可以解决非root用户crontab定时任务无法执行问题