我们的程序,在运行的过程中,会需要不定时的去执行一些脚本,
这个脚本不一定每时每刻都在执行,但有一点的是每天必须执行一次,比如结帐。
那如何让系统自动的去帮助我们执行脚本?
这就需要使用 linux 的定时任务 crontab 这个命令
crontab 是linux系统下的任务进程。开机后此进程会启动,它每隔一定时间会去自己的列表中看是否有需要执行的任务。
分 时 日 月 周几 脚本
以这样的格式去写。
crontab -e 会打开一个窗口,
如果之前定义过执行脚本的命令这里会有上一次定义过的脚本信息,
如果一次也没有定义过,这里就是空白的,什么也没有。
信息编辑好以后
:x
保存退出。系统自动执行,不需要任何重启。
下面来看一个执行php的命令:
/usr/local/php/php5.2.17/bin/php /a/a.php
/usr/local/php/php5.2.17/bin/php 这个命令是安装php,路径/bin/下面的一个文件。必须指定到这里
不然php命令无法运行。
php的路径必须正确。
定时任务的真是文件放在什么位置?
/var/spool/cron/
的 root 文件里。
使用 vim root 显示:
和使用 crontab -l 显示是一样的。
说了这么多,知道定时任务放在哪里有什么用啊?
可以通过php程序来调用shell脚本,对这个文件的更改。
一、在Crontab中使用PHP执行脚本
显示定时任务
crontab -l
编辑定时任务:
crontab -e
00 * * * * /usr/local/php/php5.2.17/bin/php /a/a.php
保存退出
每一个小时执行一次。
* * * * * /usr/local/php/php5.2.17/bin/php /a/a.php
每一分钟执行一次
* * 01 * * /usr/local/php/php5.2.17/bin/php /a/a.php
每个月1号执行一次
* 12 01 * * /usr/local/php/php5.2.17/bin/php /a/a.php
每个月1号的12点执行任务。
依次类退
/a/a.php 文件内容:
file_put_contents("/a/".time().".txt",time());
保存退出
这里不管是发送还是保存的地址必须是绝对路径,否则就会发现程序没有执行还是有错误?
反正看不见文件。
如何查看crontab是否有没有执行,查看日志文件即可
cat /var/log/cron 查看哪些日志执行了。
二、在Crontab中使用URL执行脚本
如果你的PHP脚本可以通过URL触发,你可以使用lynx或curl或wget来配置你的Crontab。
* * * * * /usr/bin/curl -o /temp.txt http://192.168.61.103/a.php
每分钟执行一次这们的命令,并把执行结果放在 /temp.txt 这个文件夹中。
-o /temp.txt -o指定的目录必须是绝对目录。 也可以不用指定 -o 这样就不记录访问网址的结果了。
每分钟运行一次,
下面的例子是使用CURL访问URL来每5分执行PHP脚本。Curl默认在标准输出显示输出。使用”curl -o”选项,你也可以把脚本的输出转储到临时文件。
*/5 * * * * /usr/bin/curl -o temp.txt http://192.168.61.103/a.php
下面的例子是使用WGET访问URL来每10分执行PHP脚本。-q选项表示安静模式。
”-O temp.txt”表示输出会发送到临时文件。 这个并不是必须加
*/10 * * * * /usr/bin/wget -q -O /temp.txt http://192.168.61.103/a.php
* * 1,10,20 * * /a/back.sh
这条命令就是每个月的1号、10号、20号 执行sh 文件。
前5个字段分别表示:
分钟:0-59
小时:1-23
日期:1-31
月份:1-12
星期:0-6(0表示周日)
还可以用一些特殊符号:
*: 表示任何时刻
,: 表示分割
-:表示一个段,如第二端里: 1-5,就表示1到5点
/n : 表示每个n的单位执行一次,如第二段里,*/1, 就表示每隔1个小时执行一次命令。也可以写成1-23/1.
一些示例:
00 8,12,16 * * * /data/app/scripts/monitor/df.sh
30 2 * * * /data/app/scripts/hotbackup/hot_database_backup.sh
10 8,12,16 * * * /data/app/scripts/monitor/check_ind_unusable.sh
10 8,12,16 * * * /data/app/scripts/monitor/check_maxfilesize.sh
10 8,12,16 * * * /data/app/scripts/monitor/check_objectsize.sh
43 21 * * * 21:43 执行
15 05 * * * 05:15 执行
0 17 * * * 17:00 执行
0 17 * * 1 每周一的 17:00 执行
0,10 17 * * 0,2,3 每周日,周二,周三的 17:00和 17:10 执行
0-10 17 1 * * 毎月1日从 17:00到7:10 毎隔1分钟 执行
0 0 1,15 * 1 毎月1日和 15日和 一日的 0:00 执行
42 4 1 * * 毎月1日的 4:42分 执行
0 21 * * 1-6 周一到周六 21:00 执行
0,10,20,30,40,50 * * * * 每隔10分 执行
*/10 * * * * 每隔10分 执行
* 1 * * * 从1:0到1:59 每隔1分钟 执行
0 1 * * * 1:00 执行
0 */1 * * * 毎时0分 每隔1小时 执行
0 * * * * 毎时0分 每隔1小时 执行
2 8-20/3 * * * 8:02,11:02,14:02,17:02,20:02 执行
30 5 1,15 * * 1日 和 15日的 5:30 执行
2.3 & 后台执行命令
当在前台运行某个作业时,终端被该作业占据;而在后台运行作业时,它不会占据终端。可以使用&命令把作业放到后台执行。
如:
30 2 * * * /data/app/scripts/hotbackup/hot_database_backup.sh &
在后台运行作业时要当心:需要用户交互的命令不要放在后台执行,因为这样你的机器就会在那里傻等。
不过,作业在后台运行一样会将结果输出到屏幕上,干扰你的工作。如果放在后台运行的作业会产生大量的输出,最好使用下面的方法把它的输出重定向到某个文件中:
如:
command >out.file 2>&1 &
在这个例子中,2>&1表示所有的标准输出和错误输出都将被重定向到一个叫做out.file 的文件中。
2.4 2>&1 含义
先看一个例子:
0 2 * * * /u01/test.sh >/dev/null 2>&1 &
这句话的意思就是在后台执行这条命令,并将错误输出2重定向到标准输出1,然后将标准输出1全部放到/dev/null 文件,也就是清空。
在这里有有几个数字的意思:
0表示键盘输入
1表示标准输出
2表示错误输出.
我们也可以这样写:
0 2 * * * /u01/test.sh >/u01/out.file & –这里没写,默认是1
0 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。
& :后台执行
测试:
ls 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 文件中。
2.5 2>&1写在后面的原因
格式:command > file 2>&1 == command 1> file 2>&1
首先是command > file将标准输出重定向到file中, 2>&1 是标准错误拷贝了标准输出,也就是同样被重定向到file中,最终结果就是标准输出和错误都被重定向到file中。
如果改成: command 2>&1 >file
2>&1 标准错误拷贝了标准输出的行为,但此时标准输出还是在终端。>file 后输出才被重定向到file,但标准错误仍然保持在终端。
另补充一点:
/etc/crontab、/etc/cron.deny 、 /etc/cron.allow文件介绍
系统调度的任务一般存放在/etc/crontab这个文件下,里面存放了一些系统运行的调度程序,通过命令我们可以看一下里面的内容:
这些任务都会是系统在运行起来后自动进行调度的。同时在/etc目录下还存放了/etc/cron.deny 和 /etc/cron.allow 文件
/etc/cron.deny 表示不能使用crontab 命令的用户
/etc/cron.allow 表示能使用crontab的用户。
如果两个文件同时存在,那么/etc/cron.allow 优先。
如果两个文件都不存在,那么只有root用户可以安排作业。
每天早上6点
0 6 * * * echo "Good morning." >> /tmp/test.txt
每两个小时
0 */2 * * * echo "Have a break now." >> /tmp/test.txt
每个月的4号和每个礼拜的礼拜一到礼拜三的早上11点
0 11 4 * 1-3 command line
二、cron 定时
cron是一个linux下的定时执行工具,可以在无需人工干预的情况下运行作业。由于Cron 是Linux的内置服务,但它不自动起来,可以用以下的方法启动、关闭这个服务:
/sbin/service crond start //启动服务
/sbin/service crond stop //关闭服务
/sbin/service crond restart //重启服务
/sbin/service crond reload //重新载入配置
表4-1 指定时间的合法范围
时间 minute hour day-of-month month-of-year day-of-week
合法值 00-59 00-23 01-31 01-12 0-6 (0 is sunday)
分钟 (0-59)
小時 (0-23)
日期 (1-31)
月份 (1-12)
星期 (0-6)//0代表星期天
除了数字还有几个个特殊的符号就是"*"、"/"和"-"、",",*代表所有的取值范围内的数字,"/"代表每的意思,"*/5"表示每5个单位,"-"代表从某个数字到某个数字,","分开几个离散的数字
crontab -e 使用cli 运行php命令的时候,php 和执行文件 必须写全称,否则可能不执行。
例如:
*/25 * * * * HTTP_ENV=develop /usr/local/php/php7/bin/php /usr/local/nginx/html/ltdata/index.php index/data2db/initRedisData
HTTP_ENV 还可以传递http头进去,这是传递的一个 环境变量 env
可以指定 crontab -e -u php-fpm 可以指定用户进行处理
crontab -e
* * * * * command
分 时 日 月 周 命令
使用权限 : 所有使用者
使用方式 :
crontab file [-u user]-用指定的文件替代目前的crontab。
crontab-[-u user]-用标准输入替代目前的crontab.
crontab-1[user]-列出用户目前的crontab.
crontab-e[user]-编辑用户目前的crontab.
crontab-d[user]-删除用户目前的crontab.
crontab-c dir- 指定crontab的目录。
crontab文件的格式:M H D m d cmd.
M: 分钟(0-59)。
H:小时(0-23)。
D:天(1-31)。
m: 月(1-12)。
d: 一星期内的天(0~6,0为星期天)。
cmd要运行的程序,程序被送入sh执行,这个shell只有USER,HOME,SHELL这三个环境变量
说明 :
crontab 是用来让使用者在固定时间或固定间隔执行程序之用,换句话说,也就是类似使用者的时程表。-u user 是指设定指定
user 的时程表,这个前提是你必须要有其权限(比如说是 root)才能够指定他人的时程表。如果不使用 -u user 的话,就是表示设
定自己的时程表。
参数 :
crontab -e : 执行文字编辑器来设定时程表,内定的文字编辑器是 VI,如果你想用别的文字编辑器,则请先设定 VISUAL 环境变数
来指定使用那个文字编辑器(比如说 setenv VISUAL joe)
crontab -r : 删除目前的时程表
crontab -l : 列出目前的时程表
crontab file [-u user]-用指定的文件替代目前的crontab。
0 11 4 * mon-wed /usr/local/etc/rc.d/lighttpd restart
每月的4号与每周一到周三的11点重启apache
0 4 1 jan * /usr/local/etc/rc.d/lighttpd restart
一月一号的4点重启apache
- 是指一个范围
/ 每隔多长时间执行一次
, 多个时间段
45 4 1,10,22 * * /usr/local/etc/rc.d/lighttpd restart
上面的例子表示每月1、10、22日的4 : 45重启apache。
$crontab -l 列出用户目前的crontab.
例子 :
#每天早上7点执行一次 /bin/ls :
0 7 * * * /bin/ls
在 12 月内, 每天的早上 6 点到 12 点中,每隔3个小时执行一次 /usr/bin/backup :
0 6-12/3 * 12 * /usr/bin/backup
周一到周五每天下午 5:00 寄一封信给 alex@domain.name :
0 17 * * 1-5 mail -s "hi" alex@domain.name < /tmp/maildata
每月每天的午夜 0 点 20 分, 2 点 20 分, 4 点 20 分....执行 echo "haha"
20 0-22/2 * * * echo "haha"
注意 :
2. 以root用户登录,创建用户的crontab文件
sudo crontab -e -u someone
PS: crontab 文件为 someone 用户创建,不好管理
3. 修改系统 crontab 文件,指定用户执行