Linux下使用crontab定时执行脚本:
vi /etc/crontab
minute hour day-of-month month-of-year day-of-week commands
分钟 小时 天 月 星期 要执行的命令
语法
crontab [ -u user ] file
或
crontab [ -u user ] { -l | -r | -e }
说明:
crontab 是用来让使用者在固定时间或固定间隔执行程序之用,换句话说,也就是类似使用者的时程表。
-u user 是指设定指定 user 的时程表,这个前提是你必须要有其权限(比如说是 root)才能够指定他人的时程表。如果不使用 -u user 的话,就是表示设定自己的时程表。
参数说明:
- -e : 执行文字编辑器来设定时程表,内定的文字编辑器是 VI,如果你想用别的文字编辑器,则请先设定 VISUAL 环境变数来指定使用那个文字编辑器(比如说 setenv VISUAL joe)
- -r : 删除目前的时程表
- -l : 列出目前的时程表
时间格式如下:
f1 f2 f3 f4 f5 program
- 其中 f1 是表示分钟,f2 表示小时,f3 表示一个月份中的第几日,f4 表示月份,f5 表示一个星期中的第几天。program 表示要执行的程序。
- 当 f1 为 * 时表示每分钟都要执行 program,f2 为 * 时表示每小时都要执行程序,其馀类推
- 当 f1 为 a-b 时表示从第 a 分钟到第 b 分钟这段时间内要执行,f2 为 a-b 时表示从第 a 到第 b 小时都要执行,其馀类推
- 当 f1 为 */n 时表示每 n 分钟个时间间隔执行一次,f2 为 */n 表示每 n 小时个时间间隔执行一次,其馀类推
- 当 f1 为 a, b, c,... 时表示第 a, b, c,... 分钟要执行,f2 为 a, b, c,... 时表示第 a, b, c...个小时要执行,其馀类推
* * * * *
- - - - -
| | | | |
| | | | +----- 星期中星期几 (0 - 7) (星期天 为0)
| | | +---------- 月份 (1 - 12)
| | +--------------- 一个月中的第几天 (1 - 31)
| +-------------------- 小时 (0 - 23)
+------------------------- 分钟 (0 - 59)
50 7 * * * python3 back-diff-config.py 意思是每天7:50执行一次脚本
back-diff-config
#!/usr/bin/python3.7
# -*- coding=utf-8 -*-
import poplib,getpass,sys
import time
import paramiko
from difflib import *
import re
import pickle
import random
import smtplib, email.utils
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.application import MIMEApplication
#需要备份的设备地址,可持续添加
#host_list = [input('IP:')]
host_list = ['172.16.16.1','172.16.16.254']
#远程链接设备
def SSHClient_SingleCMD(ip, username, password, cmd):
try:
ssh = paramiko.SSHClient()
ssh.load_system_host_keys()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(ip,port=22,username=username,password=password,timeout=5,compress=True)#SSH连接
stdin,stdout,stderr = ssh.exec_command(cmd)#执行命令
x = stdout.read()#读取回显
return x
ssh.close()
except Exception as e:
print('%stErrorn %s'%(ip,e))
#MD5值生成
def get_md5_config(host_list, username, password,operation=0):
dict_config = {}
for host in host_list:
if operation == 0:
try:
run_config = SSHClient_SingleCMD(host, 'admin', 'admin', 'show run')
list_run_config = run_config.decode().split('\r\n')
location = 0
host_location = 0
for i in list_run_config:
if re.match('.*hostname .*', i):
host_location = location
else:
location += 1
list_run_config = list_run_config[host_location:]
run_config = '\r\n'.join(list_run_config)
md5 = SSHClient_SingleCMD(host, 'admin', 'admin', 'verify /md5 system:running-config')
dict_config[host] = [run_config.encode(),md5.strip()[-32:]]
except Exception as e:
print('%stErrorn %s'%(host,e))
elif operation == 1:
try:
run_config = SSHClient_SingleCMD(host, 'admin', 'admin', 'show run')
list_run_config = run_config.decode().split('\r\n')
location = 0
host_location = 0
for i in list_run_config:
if re.match('.*hostname .*', i):
host_location = location
else:
location += 1
list_run_config = list_run_config[host_location:]
run_config = '\r\n'.join(list_run_config)
#md5 = SSHClient_SingleCMD(host, 'admin', 'admin', 'verify /md5 system:running-config')
dict_config[host] = run_config.encode()
except Exception as e:
print('%stErrorn %s'%(host,e))
elif operation == 2:
try:
#run_config = SSHClient_SingleCMD(host, 'admin', 'admin', 'show run')
md5 = SSHClient_SingleCMD(host, 'admin', 'admin', 'verify /md5 system:running-config')
dict_config[host] = md5.strip()[-32:]
except Exception as e:
print('%stErrorn %s'%(host,e))
else:
print('操作码传入错误!')
return dict_config
#配置文件对比
def diff_file(file1,file2):
txt1 = open(file1, 'r').readlines()
txt2 = open(file2, 'r').readlines()
result = Differ().compare(txt1, txt2)
return_result = '\n'.join(list(result))
return return_result
def diff_file(txt1,txt2):
txt1_list = txt1.decode().split('\r\n')
txt2_list = txt2.decode().split('\r\n')
result = Differ().compare(txt1_list, txt2_list)
return_result = '\r\n'.join(list(result))
return return_result
#邮件配置
def smtp_attachment(mailserver, username, password, From, To, Subj, Main_Body, files=None):
Tos = To.split(';')#把多个邮件接受者通过';'分开
Date = email.utils.formatdate()#格式化邮件时间
msg = MIMEMultipart()
msg["Subject"] = Subj
msg["From"] = From
msg["To"] = To
msg["Date"] = Date
part = MIMEText(Main_Body)
msg.attach(part)
if files:
for file in files:
part = MIMEApplication(open(file,'rb').read())
part.add_header('Content-Disposition', 'attachment', filename=file)
msg.attach(part)
server = smtplib.SMTP(mailserver)#连接邮件服务器
server.login(username, password)#通过用户名和密码登录邮件服务器
failed = server.sendmail(From, Tos, msg.as_string())#发送邮件
server.quit()#退出会话
if failed:
print('Falied recipients:', failed)#如果出现故障,打印故障原因!
else:
print('邮件已经成功发出!')#如果没有故障发生,打印‘No errors.’!
def rec_mail(mailserver, mailuser, mailpasswd, mailprefix):
print('Connecting...')
server = poplib.POP3(mailserver)#连接到邮件服务器
server.user(mailuser)#邮件服务器用户名
server.pass_(mailpasswd)#邮件服务器密码
try:
print(server.getwelcome())#打印服务器欢迎信息
msgCount, msgBytes = server.stat()#查询邮件数量与字节数
print('There are', msgCount, 'mail message in', msgBytes, 'bytes')#打印邮件数量与字节数
print(server.list())#打印邮件清单
for i in range(msgCount):#逐个读取邮件
hdr, message, octets = server.retr(i + 1)#读取邮件
mail_file_name = mailprefix + '_' + str(i+1) + '.txt'#本地邮件文件名
mail_file = open(mail_file_name, 'wb')#创建本地邮件文件
for line in message:
mail_file.write(line)#把邮件写入本地邮件文件
mail_file.close()#写入完毕,关闭本地邮件文件
print(mail_file_name + ' Recieved!!!')
finally:
server.quit()#退出服务器
print('Bye.')
#备份配置
def first_bak(host_list, username, password):
dict_config = get_md5_config(host_list, 'admin', 'admin')
#print(dict_config)
with open('./config_bak/Config-file', "wb") as config-file:
pickle.dump(dict_config, config-file)
print('配置备份成功!')
def find_diff(host_list, username, password):
new_md5_dict = get_md5_config(host_list, 'admin', 'admin', operation=2)
with open('./config_bak/Config-file', "rb") as config-file:
old_md5_dict = pickle.load(Pickle_config)
for x in new_md5_dict:
if new_md5_dict[x] != old_md5_dict[x][1]:
diff_md5_dict = get_md5_config(host_list, 'admin', 'admin')
diff_result = diff_file(old_md5_dict[x][0],diff_md5_dict[x][0])
#print(old_md5_dict[x][0])
#print('=='*50)
#print(diff_md5_dict[x][0])
#print(diff_result )
return x,diff_result
def check_diff():
try:
ip, config_changed = find_diff(host_list, 'admin', 'admin')
print('发现配置更改!')
id_no = str(int(random.random()*10000))
Subject = ip + ' configuration changed ' + 'reply "y1" for update db ' + id_no
Main_Body = config_changed
smtp_attachment('smtp.163.com',
'username',
'password',
'mail@163.com',
'mail@163.com',
Subject,
Main_Body)
time.sleep(300)
operation_code = rec_mail('pop.163.com', 'mail-username', 'mail-password', id_no)
if operation_code == True:
print('邮件已确认!更新数据库!')
first_bak(host_list, 'admin', 'admin')
except TypeError:
print('配置没有任何修改!')
if __name__ == '__main__':
first_bak(host_list, 'admin', 'admin')