Day 3: 系统任务自动化
学习目标
完成今天的学习后,你将能够:
- 使用Python执行系统命令
- 管理系统进程
- 实现定时任务
- 获取系统信息
技术原理
系统命令执行
Python提供了多种执行系统命令的方式:
- os.system():简单命令执行
- subprocess模块:高级子进程管理
- os.popen():获取命令输出
subprocess模块
python
import subprocess
# 执行命令并获取输出
result = subprocess.run(['ls', '-l'], capture_output=True, text=True)
print(result.stdout)
# 使用shell执行
result = subprocess.run('ls -l', shell=True, capture_output=True, text=True)定时任务
1. 使用schedule库
python
import schedule
import time
def job():
print("执行任务")
schedule.every(1).hours.do(job)
while True:
schedule.run_pending()
time.sleep(1)2. 使用系统cron
bash
# 编辑crontab
crontab -e
# 添加定时任务
0 * * * * /usr/bin/python3 /path/to/script.py案例:系统监控脚本
创建一个系统监控脚本,实现:
- 监控CPU、内存、磁盘使用率
- 检查关键进程状态
- 发送告警通知
- 记录监控日志
应用场景
1. 服务器管理
- 服务启停管理
- 配置更新
- 性能监控
2. 数据库管理
- 数据备份
- 数据清理
- 性能优化
3. 网络管理
- 网络测试
- 连接监控
- 流量统计
4. 应用部署
- 代码更新
- 服务重启
- 环境配置
代码案例
案例1:进程管理脚本
python
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
进程管理脚本
功能:查看、启动、停止系统进程
"""
import os
import sys
import signal
import subprocess
import psutil
def list_processes(filter_name=None):
"""列出进程"""
print(f"{'PID':<10}{'名称':<20}{'状态':<10}{'CPU%':<10}{'内存%':<10}")
print("-" * 60)
for proc in psutil.process_iter(['pid', 'name', 'status', 'cpu_percent', 'memory_percent']):
try:
pinfo = proc.info
# 过滤进程
if filter_name and filter_name.lower() not in pinfo['name'].lower():
continue
print(f"{pinfo['pid']:<10}{pinfo['name']:<20}{pinfo['status']:<10}"
f"{pinfo['cpu_percent']:<10.1f}{pinfo['memory_percent']:<10.1f}")
except (psutil.NoSuchProcess, psutil.AccessDenied):
pass
def start_process(command):
"""启动进程"""
try:
process = subprocess.Popen(
command,
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
print(f"进程已启动,PID: {process.pid}")
return process.pid
except Exception as e:
print(f"启动失败: {e}")
return None
def stop_process(pid):
"""停止进程"""
try:
process = psutil.Process(pid)
process.terminate()
print(f"进程 {pid} 已停止")
return True
except psutil.NoSuchProcess:
print(f"进程 {pid} 不存在")
return False
except psutil.AccessDenied:
print(f"无权限停止进程 {pid}")
return False
def main():
"""主函数"""
if len(sys.argv) < 2:
print("用法:")
print(" python process.py list [过滤名称]")
print(" python process.py start <命令>")
print(" python process.py stop <PID>")
return
action = sys.argv[1]
if action == 'list':
filter_name = sys.argv[2] if len(sys.argv) > 2 else None
list_processes(filter_name)
elif action == 'start':
if len(sys.argv) < 3:
print("错误:请提供要执行的命令")
return
command = ' '.join(sys.argv[2:])
start_process(command)
elif action == 'stop':
if len(sys.argv) < 3:
print("错误:请提供进程PID")
return
try:
pid = int(sys.argv[2])
stop_process(pid)
except ValueError:
print("错误:PID必须是数字")
else:
print(f"未知操作: {action}")
if __name__ == "__main__":
main()案例2:定时任务管理
python
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
定时任务管理脚本
功能:创建和管理定时任务
"""
import time
import schedule
from datetime import datetime
class TaskScheduler:
"""任务调度器"""
def __init__(self):
self.tasks = {}
def add_task(self, name, job, interval, unit='minutes'):
"""
添加定时任务
Args:
name: 任务名称
job: 任务函数
interval: 执行间隔
unit: 时间单位(seconds, minutes, hours)
"""
self.tasks[name] = {
'job': job,
'interval': interval,
'unit': unit,
'last_run': None,
'run_count': 0
}
# 根据单位设置调度
if unit == 'seconds':
schedule.every(interval).seconds.do(self._run_task, name)
elif unit == 'minutes':
schedule.every(interval).minutes.do(self._run_task, name)
elif unit == 'hours':
schedule.every(interval).hours.do(self._run_task, name)
print(f"已添加任务: {name} (每{interval}{unit})")
def _run_task(self, name):
"""执行任务"""
task = self.tasks[name]
print(f"\n[{datetime.now()}] 执行任务: {name}")
try:
task['job']()
task['last_run'] = datetime.now()
task['run_count'] += 1
print(f"任务 {name} 执行成功")
except Exception as e:
print(f"任务 {name} 执行失败: {e}")
def run(self):
"""运行调度器"""
print("调度器已启动,按 Ctrl+C 停止")
print("-" * 50)
try:
while True:
schedule.run_pending()
time.sleep(1)
except KeyboardInterrupt:
print("\n调度器已停止")
# 示例任务
def backup_task():
"""备份任务"""
print("执行数据备份...")
def cleanup_task():
"""清理任务"""
print("执行临时文件清理...")
def report_task():
"""报告任务"""
print("生成系统报告...")
def main():
"""主函数"""
scheduler = TaskScheduler()
# 添加任务
scheduler.add_task("数据备份", backup_task, 30, 'minutes')
scheduler.add_task("临时文件清理", cleanup_task, 1, 'hours')
scheduler.add_task("系统报告", report_task, 24, 'hours')
# 运行调度器
scheduler.run()
if __name__ == "__main__":
main()课后练习
练习1:系统命令执行
- 编写脚本,执行ping命令测试网络连通性
- 支持批量测试多个主机
- 将结果保存到文件
练习2:进程监控
- 创建进程监控脚本
- 监控指定进程的CPU和内存使用
- 超过阈值时发送告警
练习3:定时备份
- 实现文件定时备份功能
- 支持增量备份和全量备份
- 自动清理过期备份
常见问题
Q1: 如何执行需要管理员权限的命令?
A: 使用sudo并确保脚本有权限:
python
result = subprocess.run(['sudo', 'command'], capture_output=True)Q2: 如何避免子进程阻塞?
A: 使用Popen并设置超时:
python
process = subprocess.Popen(['command'])
try:
process.wait(timeout=30)
except subprocess.TimeoutExpired:
process.kill()Q3: 如何在Windows上执行Linux命令?
A: 使用WSL或Cygwin,或者使用Python的跨平台模块。
下一步学习
完成今天的学习后,建议你:
- 熟悉subprocess模块的使用
- 了解定时任务的实现方式
- 尝试编写系统监控脚本
- 准备进入Day 4的学习:参数处理与配置管理
明天我们将学习如何处理命令行参数和管理配置文件。