Python自动化运维 作业1

记得自己改名字哦

更新:

  1. https://type.dayiyi.top/index.php/archives/312/
  2. https://cmd.dayi.ink/tdhzBUosT1SeW7YEkalrIw

编程实现:

(1)程序1:监控该目录下的文件及目录,显示文件及目录变化信息;当有文件被修改时,显示修改后的文件内容。

加了点日志模块,但是好看了,大概这个样子

(2)程序2:该目录下创建配置文件student.ini,如图所示。

运行之后输出

执行prog_2.py:
文件student.ini不存在,将创建默认配置文件

(3)程序3:读取配置文件中[DEFAULT]中course的值,将其分别用gbk和utf-8进行编码,并将编码分别存入以姓名+编码(如“zhangsan-GBK”)命名的.txt文件中。

执行prog_3.py:
网络运维技术

(4)程序4:修改配置文件,将[student]中的数据项设置为学生本人的信息。

执行prog_4.py:
文件内容如下:
[DEFAULTI]
course = 网络运维技术
university = 山东科技大学
grade = 3
[student]
name = ?
class = ?
studentid = ?
sex = ?
==========修改后的值:===================
姓名: dayi
班级: 网络21
学号: 2021233333333
性别: Male

运行程序1开始进行监控,然后分别运行程序2,3,4,观察程序1的运行结果。

全部日志:(10秒执行一个程序,可以根据时间来区分)

(.venv) PS E:\dayi_\@docs_大三下\1.自动化运维\作业\作业1\dayi> py .\prog_1.py
[2024-03-07 11:14:32][INFO]: logger测试
[2024-03-07 11:14:32][INFO]: [+]当前目录为:E:\dayi_\@docs_大三下\1.自动化运维\作业\作业1\dayi
[2024-03-07 11:14:32][INFO]: [+]开始监控文件夹:E:\dayi_\@docs_大三下\1.自动化运维\作业\作业1\dayi
[2024-03-07 11:14:33][INFO]: [删除]【文件】: 路径:E:\dayi_\@docs_大三下\1.自动化运维\作业\作业1\dayi\dayi-GBK.txt
[2024-03-07 11:14:33][INFO]: [删除]【文件】: 路径:E:\dayi_\@docs_大三下\1.自动化运维\作业\作业1\dayi\dayi-UTF-8.txt
[2024-03-07 11:14:33][INFO]: [删除]【文件】: 路径:E:\dayi_\@docs_大三下\1.自动化运维\作业\作业1\dayi\student.ini
[2024-03-07 11:14:43][INFO]: [创建]【文件】: 路径:E:\dayi_\@docs_大三下\1.自动化运维\作业\作业1\dayi\student.ini
[2024-03-07 11:14:43][INFO]: [修改]【文件】: 路径:E:\dayi_\@docs_大三下\1.自动化运维\作业\作业1\dayi\student.ini
[2024-03-07 11:14:43][INFO]: 读取文件内容成功(二进制)
==============student.ini文件内容如下(二进制)==============
student.ini文件内容(二进制):
b'[DEFAULTI]\r\ncourse = \xe7\xbd\x91\xe7\xbb\x9c\xe8\xbf\x90\xe7\xbb\xb4\xe6\x8a\x80\xe6\x9c\xaf\r\nuniversity = \xe5\xb1\xb1\xe4\xb8\x9c\xe7\xa7\x91\xe6\x8a\x80\xe5\xa4\xa7\xe5\xad\xa6\r\ngrade = 3\r\n\r\n[student]\r\nname = ?\r\nclass = ?\r\nstudentid = ?\r\nsex = ?\r\n\r\n'
==============student.ini文件内容如上(二进制)==============
[2024-03-07 11:14:43][INFO]: 检测到编码为:utf-8
==============student.ini文件修改后内容如下(utf-8)==============
文件内容(utf-8):
[DEFAULTI]
course = 网络运维技术
university = 山东科技大学
grade = 3

[student]
name = ?
class = ?
studentid = ?
sex = ?


==============student.ini文件修改后内容如上(utf-8)==============
[2024-03-07 11:14:53][INFO]: [创建]【文件】: 路径:E:\dayi_\@docs_大三下\1.自动化运维\作业\作业1\dayi\dayi-UTF-8.txt
[2024-03-07 11:14:53][INFO]: [修改]【文件】: 路径:E:\dayi_\@docs_大三下\1.自动化运维\作业\作业1\dayi\dayi-UTF-8.txt
[2024-03-07 11:14:53][INFO]: 读取文件内容成功(二进制)
==============dayi-UTF-8.txt文件内容如下(二进制)==============
dayi-UTF-8.txt文件内容(二进制):
b'\xe7\xbd\x91\xe7\xbb\x9c\xe8\xbf\x90\xe7\xbb\xb4\xe6\x8a\x80\xe6\x9c\xaf'
==============dayi-UTF-8.txt文件内容如上(二进制)==============
[2024-03-07 11:14:53][INFO]: 检测到编码为:utf-8
==============dayi-UTF-8.txt文件修改后内容如下(utf-8)==============
文件内容(utf-8):
网络运维技术
==============dayi-UTF-8.txt文件修改后内容如上(utf-8)==============
[2024-03-07 11:14:53][INFO]: [创建]【文件】: 路径:E:\dayi_\@docs_大三下\1.自动化运维\作业\作业1\dayi\dayi-GBK.txt
[2024-03-07 11:14:53][INFO]: [修改]【文件】: 路径:E:\dayi_\@docs_大三下\1.自动化运维\作业\作业1\dayi\dayi-GBK.txt
[2024-03-07 11:14:53][INFO]: 读取文件内容成功(二进制)
==============dayi-GBK.txt文件内容如下(二进制)==============
dayi-GBK.txt文件内容(二进制):
b'\xcd\xf8\xc2\xe7\xd4\xcb\xce\xac\xbc\xbc\xca\xf5'
==============dayi-GBK.txt文件内容如上(二进制)==============
[2024-03-07 11:14:53][INFO]: 检测到编码为:gbk
==============dayi-GBK.txt文件修改后内容如下(gbk)==============
文件内容(gbk):
网络运维技术
==============dayi-GBK.txt文件修改后内容如上(gbk)==============
[2024-03-07 11:15:03][INFO]: [修改]【文件】: 路径:E:\dayi_\@docs_大三下\1.自动化运维\作业\作业1\dayi\student.ini
[2024-03-07 11:15:03][INFO]: 读取文件内容成功(二进制)
==============student.ini文件内容如下(二进制)==============
student.ini文件内容(二进制):
b'[DEFAULTI]\r\ncourse = \xe7\xbd\x91\xe7\xbb\x9c\xe8\xbf\x90\xe7\xbb\xb4\xe6\x8a\x80\xe6\x9c\xaf\r\nuniversity = \xe5\xb1\xb1\xe4\xb8\x9c\xe7\xa7\x91\xe6\x8a\x80\xe5\xa4\xa7\xe5\xad\xa6\r\ngrade = 3\r\n\r\n[student]\r\nname = dayi\r\nclass = \xe7\xbd\x91\xe7\xbb\x9c21\r\nstudentid = 2021233333333\r\nsex = Male\r\n\r\n'
==============student.ini文件内容如上(二进制)==============
[2024-03-07 11:15:03][INFO]: 检测到编码为:utf-8
==============student.ini文件修改后内容如下(utf-8)==============
文件内容(utf-8):
[DEFAULTI]
course = 网络运维技术
university = 山东科技大学
grade = 3

[student]
name = dayi
class = 网络21
studentid = 2021233333333
sex = Male


==============student.ini文件修改后内容如上(utf-8)==============
[2024-03-07 11:15:03][INFO]: [修改]【文件】: 路径:E:\dayi_\@docs_大三下\1.自动化运维\作业\作业1\dayi\student.ini
[2024-03-07 11:15:03][INFO]: 读取文件内容成功(二进制)
==============student.ini文件内容如下(二进制)==============
student.ini文件内容(二进制):
b'[DEFAULTI]\r\ncourse = \xe7\xbd\x91\xe7\xbb\x9c\xe8\xbf\x90\xe7\xbb\xb4\xe6\x8a\x80\xe6\x9c\xaf\r\nuniversity = \xe5\xb1\xb1\xe4\xb8\x9c\xe7\xa7\x91\xe6\x8a\x80\xe5\xa4\xa7\xe5\xad\xa6\r\ngrade = 3\r\n\r\n[student]\r\nname = dayi\r\nclass = \xe7\xbd\x91\xe7\xbb\x9c21\r\nstudentid = 2021233333333\r\nsex = Male\r\n\r\n'
==============student.ini文件内容如上(二进制)==============
[2024-03-07 11:15:03][INFO]: 检测到编码为:utf-8
==============student.ini文件修改后内容如下(utf-8)==============
文件内容(utf-8):
[DEFAULTI]
course = 网络运维技术
university = 山东科技大学
grade = 3

[student]
name = dayi
class = 网络21
studentid = 2021233333333
sex = Male


==============student.ini文件修改后内容如上(utf-8)==============

代码

记得安装依赖

prog_1

from watchdog.observers import Observer  # 导入watchdog库中的Observer类,用于监控文件系统事件
from watchdog.events import FileSystemEventHandler  # 导入FileSystemEventHandler类,用于处理文件系统事件
import time
import logging
import colorlog
import os
from colorlog.escape_codes import escape_codes
import chardet

logger = logging.getLogger()  # 获取logger实例
def log_init():
    global logger
    logger.setLevel(logging.INFO)  # 设置日志级别
    handler = colorlog.StreamHandler()  # 创建一个StreamHandler用于输出到控制台
    # -[func:%(funcName)s]
    handler.setFormatter(colorlog.ColoredFormatter(
        '[%(log_color)s%(asctime)s%(reset)s][%(log_color)s%(levelname)s%(reset)s]: %(log_color)s%(message)s',  # 设置日志输出格式
        datefmt='%Y-%m-%d %H:%M:%S',  # 设置时间格式
        reset=True,  # 重置终端属性
        log_colors={  # 设置日志级别和日期时间的颜色
            'DEBUG': 'cyan',
            'INFO': 'green',
            'WARNING': 'yellow',
            'ERROR': 'red',
            'CRITICAL': 'red,bg_white',
            'asctime': 'blue',  # 设置日期时间的颜色
        },
    ))
    logger.addHandler(handler)


def colorize_string(s, color):
    return f"{escape_codes[color]}{s}{escape_codes['reset']}"




# 用chardet来检测编码
def detect_encoding(file_path):
  # 先尝试GBK读取
  try:
    with open(file_path, 'r', encoding='gbk') as f:
       f.read()
    return 'gbk'
  except:
    with open(file_path, 'rb') as f:
      result = chardet.detect(f.read())
    return result['encoding']

# # UTF-8 和GBK的前几位编码不一样
# def detect_encoding(file_path):
#   with open(file_path, 'rb') as f:
#     first_three_bytes = f.read(3)
#   if first_three_bytes == b'\xef\xbb\xbf':
#     try:
#        open(file_path,'r',encoding="utf-8").read()
#        return 'utf-8'
#     except:
#         return 'gbk'
#   return 'gbk'

class MyHandler(FileSystemEventHandler):
    def __init__(self):
      self.emit_once = True # 减少事件触发次数
    def on_any_event(self, event):
        # 事件类型描述
        event_description = {
          'modified': colorize_string("[修改]", 'red'),
          'created': colorize_string("[创建]", 'green'),
          'deleted': colorize_string("[删除]", 'yellow'),
          'moved': colorize_string("[移动]", 'blue')
        }
        # 目录或文件描述
        file_dir_desc = {
         True: colorize_string("【目录】", 'blue'), 
         False: colorize_string("【文件】", 'yellow')  
        }

        # 是否是目录
        dir_or_file = file_dir_desc[event.is_directory]
        logger_str = f"{event_description.get(event.event_type, '未知事件'+str(event.event_type))}{dir_or_file}: 路径:{event.src_path}"
        # 记录事件信息
        logger.info(logger_str)

        # 对于文件的修改和创建事件,进一步处理
        if event.event_type in ['modified', 'created'] and not event.is_directory:
          file_name_without_path = event.src_path.split("\\")[-1]  # 从路径中提取文件名
          action = "被修改" if event.event_type == 'modified' else "被创建"
          # logger.info(f'文件: {file_name_without_path} {action}')
          
          # 修改事件
          if event.event_type == 'modified':
            # bin
            try:
               with open(event.src_path, 'rb') as file:
                 logger.info('读取文件内容成功(二进制)')
                 file_contents = file.read()
                 print(f"=============={file_name_without_path}文件内容如下(二进制)==============")
                 print(f"{file_name_without_path}文件内容(二进制):\n{file_contents}")  # 打印文件内容
                 print(f"=============={file_name_without_path}文件内容如上(二进制)==============")
            except Exception as e:
               logger.error(f'读取文件时发生错误(二进制读取失败?!): {e}') 
            # UTF-8 + GBK + ANY
            try:
              encoding=detect_encoding(event.src_path)
              logger.info("检测到编码为:"+encoding)
              with open(event.src_path, 'r', encoding=encoding) as file:
                file_contents = file.read()
                print(f"=============={file_name_without_path}文件修改后内容如下({encoding})==============")
                print(f"文件内容({encoding}):\n{file_contents}")  # 打印文件内容
                print(f"=============={file_name_without_path}文件修改后内容如上({encoding})==============")
              #下面的代码应该不会触发,历史遗留 
            except Exception as e:
                try:
                  logger.info('尝试UTF-8编码读取...')
                  with open(event.src_path, 'r',encoding="utf-8") as file:
                    logger.info('读取文件内容成功(UTF-8)')
                    file_contents = file.read()
                    print("==============新文件内容如下==============")
                    print(f"文件内容(UTF-8):\n{file_contents}")  # 打印文件内容
                    print("==============新文件内容如上==============")
                except Exception as e:
                  logger.error(f'读取文件时发生错误: {e}')  # 使用日志记录异常信息
                  logger.info('尝试GBK编码读取...')
                  try:
                      with open(event.src_path, 'r',encoding="gbk") as file:
                        logger.info('读取文件内容成功(GBK)')
                        file_contents = file.read()
                        print("==============新文件内容如下==============")
                        print(f"文件内容:\n{file_contents}")  # 打印文件内容
                        print("==============新文件内容如上==============")
                  except Exception as e:
                        logger.error(f'读取文件再次发生错误,未知报错: {e}')

def monitor_folder(path='.'):
  event_handler = MyHandler()  # 创建MyHandler实例
  observer = Observer()  # 创建Observer实例
  observer.schedule(event_handler, path, recursive=False)  # 配置Observer监控的目录和事件处理器
  observer.start()  # 启动Observer
  try:  # 等待捕获键盘中断异常
    while True:  
      time.sleep(1)  # 减少CPU占用
  except KeyboardInterrupt:  # 捕获键盘中断(Ctrl+C)
    observer.stop()  # 停止Observer
    # print("[-]捕获到键盘中断,停止监控") 
    logger.warning("[-]捕获到键盘中断,停止监控")
  observer.join()  # 等待Observer线程结束



if __name__=="__main__":  # 如果此脚本作为主程序运行
  log_init() #初始化日志
  logger.info("logger测试")
  now_path = os.getcwd()  # 获取当前脚本的路径
  logger.info("[+]当前目录为:"+now_path)
  logger.info("[+]开始监控文件夹:"+ now_path)
  monitor_folder(now_path)  # 调用monitor_folder函数开始监控当前脚本所在的目录

prog_2

import configparser
import os
def create_default_ini(filename):
    config = configparser.ConfigParser()
    config['DEFAULTI'] = {
        'course': '网络运维技术',
        'university': '山东科技大学',
        'grade': '3'
    }
    config['student'] = {
        'name': '?',
        'class': '?',
        'studentid': '?',
        'seX': '?'
    }
    with open(filename, 'w',encoding="utf-8") as configfile:
        config.write(configfile)

filename = "student.ini"
if not os.path.exists(filename):
    print(f"文件{filename}不存在,将创建默认配置文件")
    create_default_ini(filename)

prog_3

def main():
  import os
  filename = "student.ini"
  if not os.path.exists(filename):
    print(f"[PROG_3]文件{filename}不存在,程序退出")
    return
  
  # 解析配置文件
  import configparser
  config = configparser.ConfigParser()
  config.read(filename,encoding="utf-8")
  
  # 读取配置
  res = config.get('DEFAULTI', 'course')
  print(res)

  # 保存TXT
  c_name = 'dayi'

  with open(c_name+"-UTF-8.txt","w+",encoding="utf-8") as file:
    file.write(res)
  
  with open(c_name+"-GBK.txt","w+",encoding="GBK") as file:
    file.write(res)

if __name__ == '__main__':
  main()

prog_4

import os
import configparser
import os
def read_modify_output():
  # 文件名
  filename = "student.ini"
  if not os.path.exists(filename):
    print(f"[PROG_4]文件{filename}不存在,程序退出")
    return  
  config = configparser.ConfigParser()
  config.read(filename,encoding="utf-8")

  print('文件内容如下:')
  for section in config.sections():
      print(f"[{section}]")
      for key in config[section]:
          print(f"{key} = {config[section][key]}")  
  
  # 修改内容
  config.set('student', 'name', 'dayi')
  config.set('student', 'class', '网络21')
  config.set('student', 'studentid', '2021233333333')
  config.set('student', 'seX', 'Male')  
  

  # 保存文件
  with open(filename, 'w',encoding="utf-8") as configfile:
      config.write(configfile)  
 
  # 重新读取INI文件以确认修改是否成功
  config.read(filename,encoding="utf-8")
  
  # 打印修改后的值
  print("==========修改后的值:===================")
  print("姓名:", config.get('student', 'name'))
  print("班级:", config.get('student', 'class'))
  print("学号:", config.get('student', 'studentid'))
  print("性别:", config.get('student', 'seX'))


if __name__ == '__main__':
  read_modify_output()

runner

import os
import time
os.remove('dayi-GBK.txt')
os.remove('dayi-UTF-8.txt')
os.remove('student.ini')

time.sleep(10)

print("执行prog_2.py:")
os.system("py prog_2.py")

time.sleep(10)

print("执行prog_3.py:")
os.system("py prog_3.py")

time.sleep(10)

print("执行prog_4.py:")
os.system("py prog_4.py")

依赖(提前安装)

requirements.txt

chardet==5.2.0
colorama==0.4.6
colorlog==6.8.2
watchdog==4.0.0

安装:

pip install -i https://mirrors.ustc.edu.cn/pypi/web/simple chardet colorama colorlog watchdog

文件下载

https://p.dabbit.net/blog/pic_bed/sharex/_pn-2024-03-07-12-08-29_Iggypops_Attentive_Circular.rar

最后修改:2024 年 03 月 07 日
如果觉得我的文章对你有用,请随意赞赏