crontab
命令是 Unix 和 Linux 用于设置周期性被执行的指令,是互联网很常用的技术,很多任务都会设置在 crontab 循环执行。crontab 命令可以精确到分(精确到秒的一般写脚本),相当于闹钟。如果不使用 crontab ,那么任务就是常驻程序,这对你的程序要求比较高,一个要求你的程序是24X7 小时不宕机,一个是要求你的调度程序比较可靠,实际工作中,90% 的程序都没有必要花这么多时间和精力去解决上面的两个问题的,只需要写好自己的业务逻辑,通过 crontab 这 工业级程序去调度就行了。
安装完操作系统后,默认会启动此任务调度命令,crond 服务的最低侦测限制是『分钟』,所以 cron 会每分钟去读取一次 /etc/crontab
、etc/cron.d/
目录、以及 /var/spool/cron
目录中的改变 ,如果发现了改变,它们就会被载入内存。因此,只要你编辑完 /etc/crontab
这个文件,并且将它储存之后,那么 cron 的配置就自动的会来运行了!
备注:在 Linux 底下的 crontab 会自动的帮我们每分钟重新读取一次 /etc/crontab
的例行工作事项,但是某些原因或者是其他的 Unix 系统中,由于 crontab 是读到内存当中的,所以在你修改完 /etc/crontab
之后,可能并不会马上运行, 这个时候请重新启动 crond 这个服务吧!可以执行 /etc/init.d/crond restart
或 service crond restart
命令。
bashcrontab (选项) file
选项:
-e
:编辑某个用户的 crontab 文件内容。如果不指定用户,则表示编辑当前用户的 crontab 文件-l
:显示某个用户的 crontab 文件内容,如果不指定用户,则表示显示当前用户的 crontab 文件内容-r
:从 /var/spool/cron
目录中删除某个用户的 crontab 文件,如果不指定用户,则默认删除当前用户的crontab 文件;-u<用户名称>
:指定要设定计时器的用户名称,例如,“-u haha” 表示设定 haha 用户的 crontab 服务,此参数一般由 root 用户来运行;-i
:在删除用户的 crontab 文件时给确认提示。-s
:(selinux context)file
:
是命令文件的名字,表示将 file 做为 crontab 的任务列表文件并载入 crontab 。如果在命令行中没有指定这个文件,crontab 命令将接受标准输入(键盘)上键入的命令,并将它们载入 crontab。
默认情况系统并没有为我们启动 crond 服务,如果想开机启动,需要在 /etc/rc.d/rc.local
中添加 service crond start
这一行。
其他的管理命令为:
service crond start
service crond stop
service crond restart
service crond reload
Linux下的任务调度分为两类,系统任务调度和用户任务调度。
/etc/crontab
文件,这个就是系统任务调度的配置文件/var/spool/cron
目录中。其文件名与用户名一致在 /etc
目录下有一个 crontab 文件,这里存放有系统运行的一些调度程序;每个用户可以建立自己的 crontab 调度,这些文件在 /var/spool/cron
目录下
bashcat /etc/crontab
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
# For details see man 4 crontabs
# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * user-name command to be executed
前四行是用来配置crond任务运行的环境变量:
在以上各个字段中,还可以使用以下特殊字符:
注
每个系统用户都可以有自己的 crontab 文件,在 /var/spool/cron/
目录下。如果你是 root 用户,那下面有个 root 文件,建议日常备份,避免误删除导致 crontab 文件丢失。
当使用者使用 crontab 这个命令来创建工作排程之后,该项工作就会被纪录到 /var/spool/cron/
里,而且是以帐号来作为判别的。举例来说, sun 使用 crontab 后, 他的工作会被纪录到 /var/spool/cron/sun
里。但请注意,不要使用 vi 直接编辑该文件, 因为可能会由于输入语法错误导致无法运行 cron 。另外, cron 运行的每一项工作都会被纪录到 /var/log/cron
这个登录档中,所以,如果你的 Linux 不知道有否被植入木马时,也可以搜寻一下 /var/log/cron
这个登录档。
在 crontab 中添加了定时任务,但发现没有得到期望的结果,因而怀疑是 crontab 没有执行相应的任务,但怎么定位 crontab 是否执行呢?
这就需要查看 crontab 的执行历史记录,具体位置如下:/var/log/
默认情况下,crontab 中执行的日志写在 /var/log/
下,如:
bashls /var/log/cron*
/var/log/cron /var/log/cron-20221211 /var/log/cron-20221218 /var/log/cron-20221225 /var/log/cron-20230101
在 cron 文件中即可查阅已经操作过的相关定时任务。
日志是按照天排列的, /var/log/cron
只会记录是否执行了某些计划的脚本,但是具体执行是否正确以及脚本执行过程中的一些信息则 Linux 会每次都发邮件到该用户下。
bashless /var/spool/mail/root
该目录下及子目录中所有符合调度语法的文件都会被执行
以优先顺序来说, /etc/cron.allow 比 /etc/cron.deny 要优先, 而判断上面,这两个文件只选择一个来限制而已,因此,建议你只要保留一个即可, 免得影响自己在配置上面的判断!一般来说,系统默认是保留 /etc/cron.deny ,你可以将不想让他运行 crontab 的那个使用者写入 /etc/cron.deny 当中,一个帐号一行!
/etc/cron.allow
:将可以使用 crontab 的帐号写入其中,若不在这个文件内的使用者则不可使用 crontab
/etc/cron.deny
:将不可以使用 crontab 的帐号写入其中,若未记录到这个文件当中的使用者,就可以使用 crontab
里面都是脚本,分别在指定的时间里执行。
更多详细介绍,可以输入 man 5 crontab 或 man 8 cron 查阅
bashyum install crontabs -y
bashservice crond start //启动 crontab 服务 service crond stop //关闭 crontab 服务 service crond restart //重动 crontab 服务 service crond reload //重新载入配置 service crond status //查看 crontab 服务状态
bashcrontab -l
bashcrontab -e
crontab -e
是针对使用者的 cron 来设计的,如果是『系统的例行性任务』,需要编辑 /etc/crontab
这个文件。
crontab -e
这个 crontab 其实是 /usr/bin/crontab
这个运行档,但 /etc/crontab
可是一个『纯文字档』,必须用 root 的身份编辑这个文件
bashcrontab -r //删除定时任务 crontab –i //在删除用户的crontab文件时给确认提示
/var/spool/cron
目录中删除用户的crontab文件bashcrontab -l > $HOME/mycron
如果不小心误删了crontab文件,假设你在自己的 HOME目录中副本的文件名。
有些 crontab 的变体有些怪异,所以在使用 crontab 命令时要格外小心。如果遗漏了任何选项,crontab 可能会打开一个空文件,或者看起来像是个空文件。这时敲 delete 键退出,不要按,否则你将丢失 crontab 文件。
每1分钟输出时间到文件
bash* * * * * echo `date` >> $HOME/date.txt
每隔2分钟同步一次互联网时间
bashecho "*/2 * * * * /usr/bin/ntpstat time.windows.com >/dev/null 2>&1" >> /var/spool/cron/root
每小时执行 /etc/cron.hourly
目录内的脚本
bash01 * * * * root run-parts /etc/cron.hourly * */1 * * * root run-parts /etc/cron.hourly
每小时的第3和第15分钟输出时间到文件
bash3,15 * * * * echo `date` >> $HOME/date.txt
每晚的21:30重启smb
bash30 21 * * * /etc/init.d/smb restart
每天18 : 00至23 : 00之间每隔30分钟重启smb
bash0,30 18-23 * * * /etc/init.d/smb restart
每天上午8点到11点的第3和第15分钟输出时间到文件
bash3,15 8-11 * * * echo `date` >> $HOME/date.txt
每天3-5,17-20每隔30分钟执行一次脚本
bashecho "*/30 [3-5],[17-20] * * * /bin/sh /home/omc/h.sh >/dev/null 2>&1" >> /var/spool/cron/root
当天23点,第二天0点到凌晨7点 每隔1分钟执行一次脚本
bash* 23,00-07/1 * * * /bin/sh /home/omc.h.sh * 23-7/1 * * * /bin/sh /home/omc.h.sh
当在前台运行某个作业时,终端被该作业占据;而在后台运行作业时,它不会占据终端。可以使用 &
命令把作业放到后台执行。
在后台运行作业时要当心:需要用户交互的命令不要放在后台执行,因为这样你的机器就会在那里傻等。
不过,作业在后台运行一样会将结果输出到屏幕上,干扰你的工作。如果放在后台运行的作业会产生大量的输出,最好使用下面的方法把它的输出重定向到某个文件中:
bashcommand > out.file 2>&1 &
在这个例子中,2>&1表示所有的标准输出和错误输出都将被重定向到一个叫做out.file 的文件中。
bash0 2 * * * /u01/test.sh >/dev/null 2>&1 &
这句话的意思就是在后台执行这条命令,并将错误输出2重定向到标准输出1,然后将标准输出1全部放到/dev/null 文件,也就是清空。
在这里有有几个数字的意思:
注
我们也可以这样写
bash0 2 * * * /u01/test.sh 1>/u01/out.file & 0 2 * * * /u01/test.sh 2>/u01/out.file & 0 2 * * * /u01/test.sh 2>/u01/out.file 2>&1 &
将 tesh.sh
命令输出重定向到 out.file
, 即输出内容不打印到屏幕上,而是输出到 out.file
文件中。
2>&1
是将错误输出重定向到标准输出。 然后将标准输入重定向到文件 out.file
。
&1
表示的是文件描述 1,表示标准输出,如果这里少了 &
就成了数字 1,就表示重定向到文件 1。
&
:后台执行
测试
bashls 2>1 : 不会报没有2文件的错误,但会输出一个空的文件 1;
ls xxx 2>1: 没有 xxx 这个文件的错误输出到了 1 中;
ls xxx 2>&1: 不会生成 1 这个文件了,不过错误跑到标准输出了;
ls xxx >out.txt 2>&1 == ls xxx 1>out.txt 2>&1: 因为重定向符号 > 默认是1,这句就把错误输出和标准输出都传到out.txt 文件中。
格式:
bashcommand > file 2>&1 == command 1>file 2>&1
首先是 command > file
将标准输出重定向到 file
中, 2>&1
是标准错误拷贝了标准输出,也就是同样被重定向到 file
中,最终结果就是标准输出和错误都被重定向到 file
中。
如果改成: command 2>&1 >file
2>&1 标准错误拷贝了标准输出的行为,但此时标准输出还是在终端。>file 后输出才被重定向到file,但标准错误仍然保持在终端。
有时我们创建了一个 crontab,但是这个任务却无法自动执行,而手动执行这个任务却没有问题,这种情况一般是由于在 crontab 文件中没有配置环境变量引起的。
在 crontab 文件中定义多个调度任务时,需要特别注意的一个问题就是环境变量的设置,因为我们手动执行某个任务时,是在当前 shell 环境下进行的,程序当然能找到环境变量,而系统自动执行任务调度时,是不会加载任何环境变量的,因此,就需要在 crontab 文件中指定任务运行所需的所有环境变量,这样,系统执行任务调度时就没有问题了。
不要假定 cron 知道所需要的特殊环境,它其实并不知道。所以你要保证在 shell 脚本中提供所有必要的路径和环境变量,除了一些自动设置的全局变量。所以注意如下3点:
source
命令引入环境变量,如:bashcat 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 &
bash0 * * * * . /etc/profile;/bin/sh /var/www/java/audit_no_count/bin/restart_audit.sh
每条任务调度执行完毕,系统都会将任务输出信息通过电子邮件的形式发送给当前系统用户,这样日积月累,日志信息会非常大,可能会影响系统的正常运行,因此,将每条任务进行重定向处理非常重要。
例如,可以在 crontab 文件中设置如下形式,忽略日志输出:
bash0 */3 * * * /usr/local/apache2/apachectl restart >/dev/null 2>&1
/dev/null 2>&1
表示先将标准输出重定向到 /dev/null
,然后将标准错误重定向到标准输出,由于标准输出已经重定向到了 /dev/null
,因此标准错误也会重定向到 /dev/null
,这样日志输出问题就解决了。
系统级任务调度主要完成系统的一些维护操作,用户级任务调度主要完成用户自定义的一些任务,可以将用户级任务调度放到系统级任务调度来完成(不建议这么做),但是反过来却不行,root 用户的任务调度操作可以通过 crontab –uroot –e
来设置,也可以将调度任务直接写入 /etc/crontab
文件,需要注意的是,如果要定义一个定时重启系统的任务,就必须将任务放到 /etc/crontab
文件,即使在 root 用户下创建一个定时重启系统的任务也是无效的。
/etc/init.d/crond restart
解决问题。或者查看日志看某个job有没有执行 / 报错 tail -f /var/log/cron
。/var/spool/cron
中删除用户的 crontab 文件。删除了该用户的所有 crontab 都没了。%
是有特殊含义的,表示换行的意思。如果要用的话必须进行转义 %
,如经常用的 date +%Y%m%d
在 crontab 里是不会执行的,应该换成 date +%%Y%%m%%d
。本文作者:@Rrx
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!