Python可手动启停日志脚本开发及sys.args参数监听需求
Python 终端日志脚本:优雅持续运行与命令行控制
核心实现思路
针对你的需求,我们可以用命令行参数解析+信号监听/事件驱动替代生硬的while True,同时实现启动/停止的命令行控制。以下是完整的可运行代码,附带详细说明:
一、完整代码实现
import argparse import time import logging import os import signal import sys from threading import Event # 配置日志与PID文件路径 LOG_FILE = "app.log" PID_FILE = "app.pid" # 全局停止事件(线程安全的退出标志) stop_event = Event() def setup_logging(): """配置日志写入规则,以追加模式写入文件""" logging.basicConfig( filename=LOG_FILE, level=logging.INFO, format="%(asctime)s - %(message)s", datefmt="%Y-%m-%d %H:%M:%S" ) def handle_signals(signum, frame): """处理系统终止信号(Ctrl+C、kill命令)""" logging.info("收到终止信号,准备优雅退出...") stop_event.set() def start_logging(): """启动持续日志写入服务""" # 检查是否已有运行实例 if os.path.exists(PID_FILE): with open(PID_FILE, "r") as f: pid = f.read().strip() print(f"脚本已在运行,PID: {pid}") sys.exit(1) # 记录当前进程PID到文件 with open(PID_FILE, "w") as f: f.write(str(os.getpid())) # 注册信号处理函数,捕捉终止信号 signal.signal(signal.SIGINT, handle_signals) signal.signal(signal.SIGTERM, handle_signals) setup_logging() logging.info("日志服务启动成功") # 用事件驱动替代while True,支持可控退出 while not stop_event.is_set(): logging.info("服务持续运行中...") time.sleep(2) # 模拟业务间隔,可根据需求调整 # 退出前清理资源 logging.info("日志服务已停止") os.remove(PID_FILE) def stop_logging(): """停止运行中的日志服务""" if not os.path.exists(PID_FILE): print("没有运行中的日志服务") sys.exit(1) with open(PID_FILE, "r") as f: pid = int(f.read().strip()) try: # 发送终止信号给目标进程 os.kill(pid, signal.SIGTERM) print(f"已发送停止信号到PID: {pid}") # 等待进程退出后清理PID文件 time.sleep(1) if os.path.exists(PID_FILE): os.remove(PID_FILE) except ProcessLookupError: print(f"PID {pid} 不存在,已清理无效PID文件") os.remove(PID_FILE) except PermissionError: print(f"无权限终止PID {pid}") sys.exit(1) if __name__ == "__main__": # 解析命令行参数 parser = argparse.ArgumentParser(description="终端日志服务脚本") subparsers = parser.add_subparsers(dest="command", required=True) # 注册启动/停止子命令 subparsers.add_parser("start", help="启动日志服务") subparsers.add_parser("stop", help="停止日志服务") args = parser.parse_args() if args.command == "start": start_logging() elif args.command == "stop": stop_logging()
二、关键优化点说明
替代
while True的优雅方案
用threading.Event作为可触发的停止标志,配合系统信号监听(SIGINT对应Ctrl+C,SIGTERM对应kill命令),实现可控的优雅退出,避免强制终止导致的资源泄漏(比如未关闭的文件句柄)。命令行参数的规范处理
用argparse替代直接解析sys.argv,自动生成帮助文档(运行python script.py -h即可查看),参数结构清晰,新手更容易维护。进程实例管理
通过PID文件记录运行中的进程ID,确保同一时间只有一个实例运行,同时stop命令可以精准定位并终止目标进程。
三、使用方法
- 启动日志服务:
python script.py start - 停止日志服务(新开终端执行):
python script.py stop - 也可以直接用Ctrl+C在启动终端停止服务,脚本会自动清理PID文件并写入退出日志。
内容的提问来源于stack exchange,提问作者Antonio K
相关产品推荐
相关产品推荐

