linux定期执行程序——crontab

1、简介

       Linux crontab是用来定期执行程序的命令。当安装完成操作系统之后,默认便会启动此任务调度命令。注意:新创建的 cron 任务,不会马上执行,至少要过 2 分钟后才可以,当然你可以重启 cron 来马上执行。

 

2、常用命令

Ubuntu

  • apt-get install cron             // Ubuntu安装crontab
  • service cron status               // 查看crontab状态
  • service cron start                 // 启动crontab
  • service cron restart              // 重启crontab
  • service cron stop                 // 停止crontab
  • service cron                        // 查询cron可用命令
  • crontab -l                           // 检查crontab工具是否安装,查看已编辑的脚本
  • crontab -e                          // 编辑定时任务,关闭定时任务删除命令即可

Centos

  • yum install vixie-cron          // vixie-cron 软件包是cron的主程序
  • yum install crontabs            // centos安装crontab

 

3、crontab格式说明

linux定期执行程序——crontab_第1张图片

       crontab中除了分、时、日、月、周外。还可以是以下特殊字符:

  • 星号(*):代表所有可能的值,例如month字段如果是星号,则表示在满足其它字段的制约条件后每月都执行该命令操作。
  • 逗号(,):可以用逗号隔开的值指定一个列表范围,例如,“1,2,5,7,8,9”
  • 中杠(-):可以用整数之间的中杠表示一个整数范围,例如“2-6”表示“2,3,4,5,6”
  • 正斜线(/):可以用正斜线指定时间的间隔频率,例如“0-23/2”表示每两小时执行一次。同时正斜线可以和星号一起使用,例如*/10,如果用在minute字段,表示每十分钟执行一次。

 

4、系统文件:/etc/crontab

linux定期执行程序——crontab_第2张图片

       此文件负责安排由系统管理员指定的维护系统以及其他任务的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 ”前面的注释符去掉。

linux定期执行程序——crontab_第3张图片

重启rsyslog:

sudo  service rsyslog  restart

查看crontab日志:

less  /var/log/cron.log

 

6、编写定时脚本

(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 ”前面的注释符去掉。

linux定期执行程序——crontab_第4张图片

重启rsyslog:

sudo  service rsyslog  restart

查看crontab日志:

less  /var/log/cron.log

 

7、常见错误

(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)

linux定期执行程序——crontab_第5张图片

原因:

cron把屏幕输出都发送到email了,而当前环境并未安装email server,于是系统报错,解决:

不要直接向屏幕输出内容,而是重定向到一个文件。

crontab -e

将日志写到文件中:

* * * * * echo "hello" >> /home/date.log

 

8、实例

       当磁盘空间大于指定百分比后删除指定文件

(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的脚本

 

你可能感兴趣的:(Shell,Linux)