最近完成的检测系统需要现场配置,为了节约时间,所以写成自动化的Python脚本去完成,主要是os.system()的使用,运行完关闭命令行最简单的方式就是使用bat文件。长话短说,直接贴代码
一、几行代码实现OpenCV等依赖包的环境自动配置
新建一个pkg_installer.py,写入以下代码(按照自己需求自行更改libs依赖包名,在现场使用这个配置环境部署系统之前,先自己测试一下各个依赖包之间有没有冲突导致安装失败的),然后直接运行这个py文件就可以看到自己安装依赖包配置环境了:
import os
# 需要的环境依赖包列表,可以在每个包后面加上想要的版本,如numpy==1.20.3
libs = ["opencv-python", "requests", "numpy", "pillow", "pyftpdlib"]
for lib in libs:
os.system("pip install " + " -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com " + lib)
二、几行Python代码配置Windows系统下脚本开机自启
1、仅一个Python脚本开机自启,运行完成后自动关闭命令行
比如要让main.py程序在Windows下实现开机自启,可以新建一个autoStart.py文件,写入以下代码,然后右键以管理员身份运行这个autoStart.py文件即可,重启测试就可以看到main.py开机自启了,而且main.py执行完成后命令行将自动关闭:
auto_path = 'C:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\StartUp\\'
auto_bat = 'MainAutoStart.bat'
BASE_DIR = "D:\\demo" # 自行更改为main.py所在文件夹的绝对路径
with open(auto_path + auto_bat, 'w') as f:
disk = BASE_DIR.split(':')[0]
f.write(disk + ':\n') # 更换磁盘区
f.write('cd ' + BASE_DIR + '\n') # 进入main.py所在文件夹
"""
如果程序运行是在自定义的Python虚拟环境,添加下面这一行,并将VirtualEnvName修改为自己的环境名
如果不需要进入自定义虚拟环境执行脚本,则无需添加
"""
# f.write('CALL conda activate VirtualEnvName\n') # 激活Python虚拟环境
f.write('python main.py') # 执行脚本
print('自动启动程序正常!Windows bat文件已添加到开机启动:' + auto_path + auto_bat)
2、同时让多个Python脚本开机自启,程序执行结束后保留命令行
提前说一句,如果是多个程序而且还要全部在运行完后自行关闭命令行,可以根据上面 1 中的方式,对每一个程序分别创建bat文件加入开机启动。接下来这种是保留命令行的(主要是为了观察命令行log信息),比如除了main.py,还要让FTPServer.py(或者更多)同时开机自启。
(1)新建一个autoStart.py文件,并写入以下代码:
import os
# 启动FTP服务器端脚本程序
os.system('start cmd.exe @cmd /k python FTPServer.py')
# 启动系统主程序
os.system('start cmd.exe @cmd /k python main.py ' + channel)
(2)新建一个bat.py文件,写入代码,然后右键以管理员身份运行bat.py即可,重启测试可以看到FTPServer.py和main.py都开机自启了,而且这两个py文件启动后的命令行不会自动关闭:
auto_path = 'C:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\StartUp\\'
auto_script = 'AutoStart.bat'
BASE_DIR = "D:\\demo" # 自行更改为main.py所在文件夹的绝对路径
with open(auto_path + auto_script, 'w') as f:
disk = BASE_DIR.split(':')[0]
f.write(disk + ':\n')
f.write('cd ' + BASE_DIR + '\n')
# f.write('CALL conda activate TruckWeight\n')
f.write('python autoStart.pyc')
print('自动启动程序正常!Windows bat文件已添加到开机启动:' + auto_path + auto_script)
三、周期性自动执行程序且每次自动关闭命令行窗口
这里代码举例展示简单的完整用法思路,主要解决的问题是:项目最初要求所有内容图片一直留存,后来硬盘满了,又让删除一个月之前的所有文件记录,每台服务器文件夹很多,按照日期命名的,那当然不可能耗费时间去挨个手动删除。。。
所以想用Python代替,经过测试发现Python的os.remove()等删除四五百G的内容会造成服务器卡顿,就换成Windows系统命令行直接删除文件夹的方式,实现一个周期性自动批量删除过期文件夹的Python脚本autoClean.py,让autoClean.py脚本启动之后,周期性打开命令行,去执行过期文件判断和清理脚本。
为了避免周期性的打开命令行,导致命令行的累加占用大量系统资源,因此需要考虑每次清理完成后,都自动关闭清理操作的命令行,所以使用的是上述第二节 1 中创建bat的方式,代码如下:
# -*- coding: UTF-8 -*-
"""
Coding is an Art
Create on 2022/3/12 22:09
@Author:YJ Zhao
"""
import os
import time
import datetime
BASE_DIR = "D:\\demo" # 项目根目录
save_root = BASE_DIR + "\\history_files" # 需要监控清理的文件夹,里面包含的全是以年月日命名的文件夹,例如20220212
clean_bat_file = BASE_DIR + '\\OutTimeImagesClear.bat'
DAY = 30 # 允许文件夹保留的最长天数
def delete_dir(path, file_data):
file_created_time = file_data[:4] + "-" + file_data[4:6] + "-" + file_data[-2:]
today = datetime.datetime.now().strftime('%Y-%m-%d')
today = datetime.datetime.strptime(today, "%Y-%m-%d")
file_created_day = datetime.datetime.strptime(file_created_time, "%Y-%m-%d")
days = (today - file_created_day).days
if days >= DAY:
with open(clean_bat_file, 'a') as fw:
# 启动命令行执行删除整个文件夹包括其中所有文件的指令
fw.write('rmdir ' + path.replace('/', '\\') + '\\' + file_data + ' /S /Q\n')
if __name__ == "__main__":
# print("超过30天的图片将自动删除!\n自动清理程序运行中,请勿关闭......")
while True:
print(datetime.datetime.fromtimestamp(time.time()).strftime('%Y-%m-%d %H:%M:%S') + ':正在检查过期图片...')
data_names = []
try:
data_names = os.listdir(save_root)
for data in data_names:
print(data)
delete_dir(save_root, data)
except Exception as e:
pass
if len(data_names):
if os.path.exists(clean_bat_file):
os.system(clean_bat_file)
print(datetime.datetime.fromtimestamp(time.time()).strftime('%Y-%m-%d %H:%M:%S') + ':过期图片自动清理完成!')
if os.path.exists(clean_bat_file):
os.remove(clean_bat_file)
print("超过30天的图片将自动删除!\n定时自动清理程序运行中,请勿关闭......")
time.sleep(86400)
温馨提示:
如果要用本文的周期性批量删除大量文件夹,或者删除指令时,建议先创建几个文件夹或文件进行测试,了解或熟悉删除功能后再使用,避免造成文件误删!!!
以上删除文件夹使用的是Windows命令行下的rmdir指令,最后的 /S /Q表示:
/S 除目录本身外,还将删除指定目录下的所有子目录和文件。用于删除目录树。
/Q 安静模式,带 /S 删除目录树时不要求确认