Linux crontab

Brief

无论是做开发还是做运维的程序猿,crontab命令是必须用到的命令。

##目录介绍

  • /var/spool/cron/ 目录下存放的是每个用户包括root的crontab任务,每个任务以创建者的名字命名。J在这里面改成自己的用户名,就能看到已经设置的crontab作业。

sudo cat /var/spool/cron/root
  • /etc/crontab 这个文件负责调度各种管理和维护任务。J就是一些配置而已。

sudo cat /etc/crontab

SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/

# 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
  • /etc/cron.d/ 这个目录用来存放任何要执行的crontab文件或脚本。我们还可以把脚本放在/etc/cron.hourly、/etc/cron.daily、/etc/cron.weekly、/etc/cron.monthly目录中,让它每小时/天/星期、月执行一次。J就是不用设置启动时间,直接放在这些目录下,就能定时执行。

流程介绍

1.查看crontab定时任务

crontab -l
sudo crontab -u root -l #查看指定用户的crontab

2.编辑定时任务【删除-添加-修改】

crontab -e
sudo crontab -u root -e #编辑指定用户的crontab
0 12 * * * (/usr/local/bin/python /data2/test2/data/GetDictData.py >/dev/null 2>&1 &)
  • The & makes the command run in the background.

  • 在shell脚本中,默认情况下,总是有三个文件处于打开状态,标准输入(键盘输入)、标准输出(输出到屏幕)、标准错误(也是输出到屏幕),它们分别对应的文件描述符是0,1,2 。

    • 1,对于下面两个命令其实效果一样。一般来说,"1>" 通常可以省略成 ">"。

      • ls GetDictData.py 1> test.out

      • ls GetDictData.py > test.out

    • 就是说指定1和2可以分别输出正确和错误的结果&2表示2输出通道,&1表示1输出通道。

      • ls a.txt b.txt 1>file.out 2>&1

      • 输出ls: b.txt: No such file or directory a.txt

    • 输出不只1和2,还有其他的类型,这两种只是最常用和最基本的。

  • 可以将/dev/null看作"黑洞"。它非常等价于一个只写文件. 所有写入它的内容都会永远丢失。而尝试从它那儿读取内容则什么也读不到。然而,/dev/null对命令行和脚本都非常的有用。

    • 禁止标准输出。cat $filename >/dev/null # 文件内容丢失,而不会输出到标准输出。

    • 禁止标准错误:2>/dev/null这样错误信息[标准错误]就被丢到太平洋去了。

  • 1>/dev/null 首先表示标准输出重定向到空设备文件,也就是不输出任何信息到终端,说白了就是不显示任何信息。 2>&1 接着,标准错误输出重定向等同于 标准输出,因为之前标准输出已经重定向到了空设备文件,所以标准错误输出也重定向到空设备文件。

实际例子

#!/usr/bin/env python
#coding=utf-8

import urllib
import urllib2
import sys
import os
import time
import datetime
import socket
import copy
import logging
import logging.handlers
reload(sys)
sys.setdefaultencoding('utf8')
socket.setdefaulttimeout(2.0)
__version = '1.1'
__author = 'jimmylian'

etcdir = ''
datadir = ''
logdir = ''

def GetLogger(logdir, loglevel):
        """keep logfile change another file everyday"""
        filename = r"/log_update"
        myloglevel = 20
        tmploglevel = int(loglevel) / 10 * 10
        if tmploglevel >= 0 and tmploglevel <= 50:
                myloglevel = tmploglevel

        handler = logging.handlers.RotatingFileHandler(logdir+filename, maxBytes = 20*1024*1024, backupCount = 10)
        fmt = '%(asctime)s [line:%(lineno)d] [%(levelname)s] %(message)s'
        formatter = logging.Formatter(fmt)
        handler.setFormatter(formatter)
        logger = logging.getLogger('GetDictData')
        logger.addHandler(handler)
        logger.setLevel(myloglevel)
        return logger

def GetDateBefore(daydelta,split=''):
        today = datetime.date.today()
        bfyesterday = today - datetime.timedelta(days = daydelta)
        if split != '':
                fmt = '%Y'+split+'%m'+split+'%d'
        else:
                fmt = '%Y%m%d'
        return bfyesterday.strftime(fmt)

def DownHttpFile(url, filename, logger):
        tmpfile = "%s%s_tmp"%(datadir, filename)
        try:
                f = urllib2.urlopen(url)
                data = f.read()
                with open(tmpfile, 'wb') as code:
                        code.write(data)
        except Exception, e:
                logger.error("download file error %s"%e)
                return False
        filepath = "%s%s"%(datadir, filename)
        os.rename(tmpfile, filepath)
        return True

def process(logger):
        url = "http://XXXX.cn/XXX_info_1_%s"%(GetDateBefore(1, ''))
        flag = DownHttpFile(url, "info_1.txt", logger)
        path = '%sinfo_1.txt'%(datadir)
        destpath = '/info_1_%s.txt'%(GetDateBefore(1, ''))
        if not flag:
                if os.path.exists(destpath):
                        os.unlink(destpath)
                logger.info("download file %s failed"%(url))
                return
        os.rename(path, destpath)
        logger.info("download file %s done"%(url))
        rmpath = '/info_1_%s.txt'%(GetDateBefore(3, ''))
        if os.path.exists(rmpath):
            os.remove(rmpath)
            logger.info("remove file %s done"%(rmpath))
        else:
            logger.info("remove file %s failed"%(rmpath))

def process1(logger):
        url = "http://XXXX.cn/XXX_info_2_%s"%(GetDateBefore(1, ''))
        flag = DownHttpFile(url, "info_2.txt", logger)
        path = '%sinfo_2.txt'%(datadir)
        destpath = '/info_2_%s.txt'%(GetDateBefore(1, ''))
        if not flag:
                if os.path.exists(destpath):
                        os.unlink(destpath)
                logger.info("download file %s failed"%(url))
                return
        os.rename(path, destpath)
        logger.info("download file %s done"%(url))
        rmpath = '/info_2_%s.txt'%(GetDateBefore(3, ''))
        if os.path.exists(rmpath):
            os.remove(rmpath)
            logger.info("remove file %s done"%(rmpath))
            #os.system("/data1/XXXXX/upload/apache-cat-8.5.71/bin/shutdown.sh")
            #time.sleep(10)
            #os.system("/data1/XXXXX/upload/apache-cat-8.5.71/bin/startup.sh")
            #logger.info("restart tomcat success")
        else:
            logger.info("remove file %s failed"%(rmpath))

def __main__():
        global datadir
        global logdir
        mybasedir = "%s"%(os.path.dirname(sys.argv[0]))
        if mybasedir == '':
                mybasedir = '.'
        datadir = "%s/data/"%(mybasedir)
        logdir = "%s/log/"%(mybasedir)
        logger = GetLogger(logdir, 20)
        runstr = ''
        for keys in sys.argv:
                runstr = "%s %s"%(runstr, keys)
        logger.info(runstr)
        process(logger)
        process1(logger)

if __name__ == "__main__":
        __main__()

Reference

Last updated