?
更好使用crontab,和解决crontab使用问题。本文分析的是Paul?Vixie版本crontab和crond。一般可通过执行“man?crontab”查看AUTHOR是不是“Paul?Vixie”。
1)?crond是一个后台守护程序,定时执行由它负责;
2)?crontab是crond的命令行工具,通过它来增删改定时任务,不同用户的crontab是独立分开的。
crontab启动后,会首先切换当前目录,当前目录由宏CRONDIR定义(pathnames.h中):
| #ifndef?CRONDIR /*?CRONDIR?is?where?cron(8)?and?crontab(1)?both?chdir ?*?to;?SPOOL_DIR,?CRON_ALLOW,?CRON_DENY,?and?LOG_FILE ?*?are?all?relative?to?this?directory. ?*/ #define?CRONDIR "/var/cron" #endif |
|:----|
老版本一般为/var/cron,新版本目录为:/var/spool。
接下来会检查用户是否有权限执行crontab,比如用户名密码过期了则不能执行。检查通过后根据命令行参数分成4个命名分别执行:
1)?list_cmd:对应于crontab?-l;
2)?delete_cmd:对应于crontab?-r;
3)?edit_cmd:对应于crontab?-e
4)?replace_cmd:对应于crontab?filepath。
crontab默认使用宏_PATH_VI指定的编程器,文件/usr/include/paths.h定义了_PATH_VI:
| #define????_PATH_VI????????"/usr/bin/vi" |
|:----|
但如果系统没有文件/usr/include/paths.h或没有定义_PATH_VI,则为/usr/ucb/vi:
| #if?defined(_PATH_VI) #?define?EDITOR?_PATH_VI #else #?define?EDITOR?"/usr/ucb/vi" #endif |
|:----|
除此外,crontab还支持从环境变量VISUAL和EDITOR读取采用哪个编辑器,其中先读取VISUAL,如果没有指定再读取EDITOR。
“crontab?-e”的完整工作流如下:
以用户root为例:
1)?切换当前目录为“/var/cron”;
2)?拼写文件名“tabs/username”,假设用户名为root,则为“tabs/root(新版本文件为:cron/root)”,完整的路径为:/var/cron/tabs/root。文件tabs/root的内容和命令“crontab?-l”的输出相同;
3)?打开文件/var/cron/tabs/root,然后取得文件的访问时间和修改时间。如果文件不存在,则读取/dev/null的访问时间和修改时间;
4)?生成格式为“crontab.XXXXXXXXXX”的临时文件,比如:crontab.b2gvnE;
5)?修改临时文件的owner;
6)?将文件tabs/root的内容逐字符复制到临时文件中;
7)?取得编辑用的编辑器,默认为“/usr/bin/vi”;
8)?fork一个子进程;
9)?通过execlp执行/usr/bin/vi;
10)?等待vi进程退出;
11)?如果vi正常退出,检查修改时间,如果有变化,则执行replace_cmd;
12)?replace_cmd过程上,会加上头:
| /*?write?a?signature?at?the?top?of?the?file. ?* ?*?VERY?IMPORTANT:?make?sure?NHEADER_LINES?agrees?with?this?code. ?*/ fprintf(tmp,?"#?DO?NOT?EDIT?THIS?FILE?-?edit?the?master?and?reinstall.\n"); fprintf(tmp,?"#?(%s?installed?on?%-24.24s)\n",?Filename,?ctime(&now)); fprintf(tmp,?"#?(Cron?version?%s?--?%s)\n",?CRON_VERSION,?rcsid); |
|:----|
13)?replace_cmd会创建一个新的位于当前目录(比如/var/cron或/var/spool)下的临时文件;
14)?然后复制原来的临时文件内容到瓣的临时文件中,并检查语法;
15)?完成再调用rename将临时文件名改为第2步取得的正式文件名;
16)?更新文件的访问时间和修改时间。
1)?“crontab?-e”未退出前的修改但已保存是否生效?
2)?crontab中定义的环境变量,注释是否可以在同一行,如:
| STARTDATE=2017-12-18?#?开始日期 |
|:----|
老版本的crond,修改改需要重启进程才会生效,新版本crond通过inotify监控文件变化,修改后不用重启即会生效。
系统crontab文件,在加载用户crontab前会先加载/etc/crontab,而且/etc/crontab总是属性root用户。
有关crontab更多,请浏览《cron运行原理》:/developer/article/1183262。
?