Linux crontab是用来定期执行程序的命令。当安装完成操作系统之后,默认便会启动此任务调度命令。注意:新创建的 cron 任务,不会马上执行,至少要过 2 分钟后才可以,当然你可以重启 cron 来马上执行。
Ubuntu:
Centos:
crontab中除了分、时、日、月、周外。还可以是以下特殊字符:
此文件负责安排由系统管理员指定的维护系统以及其他任务的crontab。
(1)配置环境变量
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/
这四行是用来配置crond任务运行的环境变量,第一行SHELL变量指定了系统要使用哪个shell,这里是bash,第二行PATH变量指定了系统执行命令的路径,第三行MAILTO变量指定了crond的任务执行信息将通过电子邮件发送给root用户,如果MAILTO变量的值为空,则表示不发送任务执行信息给用户,第四行的HOME变量指定了在执行命令或者脚本时使用的主目录。
(2)命令解析
17 * * * * root cd / && run-parts --report /etc/cron.hourly
在此命令的定时时间后是一个root,代表的是执行的级别为root,当然,也可改为其他用户。“cd /”表示进入到根目录,“&&”同时,“run-parts”运行这部分,后面接的“/etc/cron.hourly”是一个目录内(/etc/cron.hourly)的所有可执行文件。故,此行的命令的含义是:/etc/cron.hourly下的脚本会在每小时的17分运行。后面三行也是类似的意思!你可以到 /etc/ 底下去看看,系统本来就预设了这4个目录!你可以将每天需要执行的命令直接写到/etc/cron.daily即可,而不需要使用到crontab -e的程式!
(3)存放crontab文件
/etc/cron.d/ 这个目录用来存放任何要执行的crontab文件或脚本。
(4)设置环境变量EDITOR
在考虑向cron进程提交一个crontab文件之前,首先要做的一件事情就是设置环境变量EDITOR。cron进程根据它来确定使用哪个编辑器编辑crontab文件。99%的UNIX和LINUX用户都使用vi,如果你也是这样,那么你就编辑$ HOME目录下的. profile文件,在其中加入这样一行:
EDITOR=vi; export EDITOR
5、日志:/var/log/cron.log
在该以上目录中为找不到该日志,则修改sudo vim /etc/rsyslog.d/50-default.conf,将“cron.* /var/log/cron.log ”前面的注释符去掉。
重启rsyslog:
sudo service rsyslog restart
查看crontab日志:
less /var/log/cron.log
(1)创建自己的crontab脚本,如wzhcrontab,在此文件中编写要执行的定时任务
(2)把这个新创建的文件作为cron命令的参数:
crontab [crontab_name],比如crontab wzhcrontab
同时在/var/spool/cron会生成用户名的副本,后续修改的定时脚本都会体现在此文件中。
(3)列出crontab文件:
crontab -l
(4)直接编辑脚本
实际上可以不用新建自己的文本,可直接使用一下命令直接编译脚本文件:
crontab -e
第一次使用此命令的时候会让你选择编译器,如vim、nano等,然后即可开始编辑脚本。
(5)日志:/var/log/cron.log
在该以上目录中为找不到该日志,则修改sudo vim /etc/rsyslog.d/50-default.conf,将“cron.* /var/log/cron.log ”前面的注释符去掉。
重启rsyslog:
sudo service rsyslog restart
查看crontab日志:
less /var/log/cron.log
(1)打印出错
问题:
Jun 11 17:05:01 imisun CRON[10269]: (wengzh6) CMD (/bin/echo 'date' > /dev/console)
Jun 11 17:05:01 imisun CRON[10268]: (CRON) info (No MTA installed, discarding output)
原因:
cron把屏幕输出都发送到email了,而当前环境并未安装email server,于是系统报错,解决:
不要直接向屏幕输出内容,而是重定向到一个文件。
crontab -e
将日志写到文件中:
* * * * * echo "hello" >> /home/date.log
当磁盘空间大于指定百分比后删除指定文件
(1)获取指定日期前的时间
#!/bin/sh
. /etc/profile
get_date_days_before(){
sec=`date -d $1 +%s`
sec_7daysbefore=$((sec - 86400*7))
#echo $sec_7daysbefore
days_before=`date -d @$sec_7daysbefore +%F`
echo $days_before
}
if [ 1 -eq $# ]
then
today=$1
dates=`get_date_days_before $1`
else
today=`date -d -1days '+%Y-%m-%d'`
dates=`date -d -7days '+%Y-%m-%d'`
fi
echo $dates
输出:
(2)列出某个文件夹中的所有文件的路径
home="/data/wengzh6/www/record/storage/"
dir=`ls $home`
for devices in $dir
do
devicepath="$home$devices"
#echo $devicepath
dir2=`ls $devicepath`
#echo $dir2
for dates in $dir2
do
date="$devicepath/$dates"
echo $date
done
done
(3)显示磁盘指定分区百分比
#!/bin/sh
# df -h:查看硬盘信息
# sed '1d':删除第一行
# awk '{print $5}':打印第5列
# sed 's/%//g' :将%替换成空,g是全局的意思。
# sed -n 1p:显示修改(-n选项)的第一行
# a1-4是检查磁盘分区信息
a1=$(df -h|sed '1d'|awk '{print $5}'|sed 's/%//g'|sed -n 1p)
a2=$(df -h|sed '1d'|awk '{print $5}'|sed 's/%//g'|sed -n 2p)
a3=$(df -h|sed '1d'|awk '{print $5}'|sed 's/%//g'|sed -n 3p)
a4=$(df -h|sed '1d'|awk '{print $5}'|sed 's/%//g'|sed -n 4p)
# b1-4是把分区名过滤出来
b1=$(df -h|sed 1d|awk '{print $1}'|sed -n 1p)
b2=$(df -h|sed 1d|awk '{print $1}'|sed -n 2p)
b3=$(df -h|sed 1d|awk '{print $1}'|sed -n 3p)
b4=$(df -h|sed 1d|awk '{print $1}'|sed -n 4p)
# 当前日期(年-月-日 时:分:秒)
DAY=$(date +%F\ %T)
# 获取“df -h”获取到的信息的前5行的第8列信息
df -h | awk '{print $5}' | head -8 | tail | grep -oP '\d+'
(4)磁盘大于指定百分比删除前一个月日志
!/bin/sh
. /etc/profile
# 获取7天前的时间
get_date_days_before(){
sec=`date -d $1 +%s`
sec_7daysbefore=$((sec - 86400*7))
#此处不打印会返回错误,使用echo返回
echo $sec_7daysbefore
#days_before=`date -d @$sec_7daysbefore +%F`
#echo $days_before
}
if [ 1 -eq $# ]
then
today=$1
before_dates=`get_date_days_before $1`
else
#格式输出
#today=`date -d -1days '+%Y-%m-%d'`
#before_dates=`date -d -7days '+%Y-%m-%d'`
#时间戳输入
today=`date -d -1days +%s`
before_dates=`date -d -7days +%s`
fi
echo "before_date = " `date -d -7days '+%Y-%m-%d'`
# 获取磁盘百分比
percent=`df -h|sed '1d'|awk '{print $5}'|sed 's/%//g'|sed -n 7p`
echo "percent = " $percent
if [ $percent -gt 30 ]
then
# 获取指定天数前的文件
home="/data/wengzh6/www/record/storage/"
dir=`ls $home`
for devices in $dir
do
devicepath="$home$devices"
#echo $devicepath
dir2=`ls $devicepath`
#列出该文件所在路径
for dates in $dir2
do
#列出各个文件日期
#echo $dates
date_stamp=`date -d ${dates} +%s`
#echo $date_stamp
#echo $before_dates
if [ $date_stamp -le $before_dates ]
then
echo "delete file: "
file_path="$devicepath/$dates"
echo $file_path
`rm -r $file_path`
fi
done
done
fi
(5)crontab执行脚本文件
0 15 * * * /home/test.sh
该命令会在每天的15点0分的时候执行test.sh的脚本