Python实现多BAT文件分时段每日自动执行

 更新时间:2026年07月24日 09:23:17   作者:幸福清风  
本文将深度剖析 Windows 定时任务间歇性失效的核心原因,并提供两套成熟可用的 Python 多时段调度 BAT 方案,一套轻量化常驻运行、一套系统级稳定无人值守,彻底根治定时任务失效问题,开箱即用

很多开发者、运维日常都会用到 Windows 定时任务,用来自动执行 BAT 批处理脚本、数据备份、日志清理、程序重启等操作。但几乎所有人都遇到过一个无解问题:定时任务时而运行、时而不运行,手动点击执行百分百正常,到点却莫名失效

尤其是需要多个 BAT 文件、不同时间段分开运行的场景,原生 Windows 计划任务配置繁琐、隐性坑极多,经常出现任务卡死、凭据失效、条件拦截、进程堆积等问题。

本文将深度剖析 Windows 定时任务间歇性失效的核心原因,并提供两套成熟可用的 Python 多时段调度 BAT 方案,一套轻量化常驻运行、一套系统级稳定无人值守,彻底根治定时任务失效问题,开箱即用。

一、先搞懂:为什么 Windows 定时任务偶尔不运行?(核心坑点)

绝大多数定时任务失效,不是系统 bug,是隐性配置不匹配、运行环境不一致导致,手动运行和定时运行是两套完全不同的环境。

1.1 运行身份与凭据失效(最高频)

默认勾选「仅当用户登录时运行」,电脑锁屏、注销、重启后无人登录,任务直接跳过。

同时,如果选择「不管用户是否登录都要运行」,保存的是当时的账户密码,Windows 修改登录密码后,定时任务凭据直接过期,出现随机失效。

普通用户权限不足,会导致读写系统目录、操作共享文件、执行权限命令间歇性失败。

1.2 条件规则拦截(最隐蔽)

计划任务「条件」选项卡中,任意一条不满足,任务直接不触发,且日志提示极不明显:

  • 笔记本默认勾选「仅交流电源运行」,电池模式直接跳过任务
  • 开启「仅计算机空闲时运行」,电脑有操作、CPU占用高则不执行
  • 绑定网络连接,Wi-Fi/网线短暂断连,任务直接终止

1.3 工作目录与路径问题(手动正常、定时异常)

手动运行 BAT 时,工作目录是脚本所在文件夹;Windows 定时任务默认工作目录是 C:\Windows\System32

如果 BAT 脚本中使用相对路径读取文件、调用程序,定时运行会直接找不到文件,表现为“任务启动了但没效果”。同时路径含空格不加分号,也会导致执行失败。

1.4 任务卡死、进程堆积阻塞后续任务

默认配置:任务正在运行时,不启动新实例。如果上一次 BAT 脚本卡死、进程常驻,后续所有定时任务全部跳过,是典型的“第一次正常、后续全失效”。

二、多 BAT 分时段运行方案选型

针对「多个 BAT 文件、不同时间每日定时运行」的需求,提供两套落地方案,按需选择:

方案优点缺点适用场景
Python Schedule 常驻调度配置简单、一键修改时间和脚本、无需操作系统计划任务需要常驻运行、窗口关闭即失效、重启需手动启动测试环境、短期定时、频繁修改任务
Windows系统计划任务+Python入口系统级稳定、后台运行、锁屏重启不失效、任务互不干扰配置稍多,需管理员权限创建任务生产环境、长期无人值守、服务器运行

三、方案一:Python 常驻定时(多 BAT 分时段执行)

基于 schedule 库实现,单文件配置所有任务,支持自定义时间、多脚本、超时防卡死、日志输出,新手友好。

3.1 安装依赖

pip install schedule

3.2 完整可运行代码

import schedule
import time
import subprocess
from pathlib import Path

# ====================== 自定义配置区(按需修改)======================
# 格式:(每日执行时间, BAT脚本绝对路径)
task_list = [
    ("08:30", r"D:\script\a.bat"),
    ("12:10", r"D:\script\b.bat"),
    ("18:45", r"D:\script\c.bat"),
    ("22:00", r"D:\script\d.bat"),
]
RUN_TIMEOUT = 3600  # 任务最大运行时长(秒),防止卡死
# ====================================================================

def execute_bat(bat_path):
    """执行单个BAT脚本并输出日志"""
    bat_file = Path(bat_path)
    work_dir = str(bat_file.parent)
    now_str = time.strftime("%Y-%m-%d %H:%M:%S")
    print(f"\n[{now_str}] 开始执行任务:{bat_path}")

    try:
        # 指定工作目录、捕获输出、超时终止
        proc = subprocess.run(
            bat_path,
            cwd=work_dir,
            shell=True,
            capture_output=True,
            text=True,
            timeout=RUN_TIMEOUT
        )
        print("任务输出:\n", proc.stdout)
        if proc.stderr:
            print("任务错误:\n", proc.stderr)
        print(f"任务执行完成,返回码:{proc.returncode}")
    except subprocess.TimeoutExpired:
        print(f"【超时终止】{bat_path} 运行超时,已强制结束进程")
    except Exception as e:
        print(f"【执行异常】{bat_path} 出错:{str(e)}")

# 批量注册所有定时任务
for run_time, bat_path in task_list:
    schedule.every().day.at(run_time).do(execute_bat, bat_path=bat_path)
    print(f"✅ 注册成功:每日 {run_time} 执行 {bat_path}")

print("\n🚀 多任务定时调度已启动,保持窗口打开即可运行")
# 持续检测定时任务
while True:
    schedule.run_pending()
    time.sleep(20)

3.3 优缺点说明

优势:无需操作系统定时任务界面,增删任务只需修改数组,支持超时防卡死,全程日志可视化。

劣势:脚本窗口关闭、程序崩溃、电脑重启后定时失效,仅适合测试和短期使用。

四、方案二:系统级稳定方案(Windows计划任务+Python通用入口)

这是生产环境首选方案,彻底解决定时任务偶发失效问题,依托 Windows 系统调度服务,锁屏、后台、重启均可自动运行,多个任务互不干扰。

4.1 通用执行入口脚本(bat_runner.py)

统一接收 BAT 路径参数,实现一个脚本调用所有批处理,自动记录运行日志。

import sys
import subprocess
from pathlib import Path
import time

def run_single_bat(bat_path):
    # 初始化路径与日志
    bat_file = Path(bat_path)
    work_dir = str(bat_file.parent)
    log_path = work_dir / "task_log.txt"
    now = time.strftime("%Y-%m-%d %H:%M:%S")
    log_lines = [f"\n===== {now} 运行任务:{bat_path} ====="]

    try:
        # 执行BAT脚本
        proc = subprocess.run(
            bat_path,
            cwd=work_dir,
            shell=True,
            capture_output=True,
            text=True,
            timeout=3600
        )
        # 记录输出与错误
        log_lines.append(proc.stdout)
        if proc.stderr:
            log_lines.append("错误信息:\n" + proc.stderr)
        log_lines.append(f"任务返回码:{proc.returncode}")
    except Exception as e:
        log_lines.append(f"任务执行异常:{str(e)}")

    # 追加写入日志文件
    with open(log_path, "a", encoding="utf-8") as f:
        f.write("\n".join(log_lines))

if __name__ == "__main__":
    # 接收命令行参数,执行对应BAT
    if len(sys.argv) >= 2:
        run_single_bat(sys.argv[1])
    else:
        print("用法:python bat_runner.py 【BAT文件绝对路径】")

4.2 一键批量创建系统定时任务(管理员运行)

无需手动逐个配置计划任务,Python 调用系统命令批量生成所有分时段任务,自动配置最高权限、每日执行、强制覆盖。

import subprocess

# 【请自行修改为本地真实路径】
PYTHON_EXE = r"C:\Python311\python.exe"
RUNNER_SCRIPT = r"D:\script\bat_runner.py"

# 多任务配置:任务名称、执行时间、BAT路径
tasks = [
    ("Task_Bat0830", "08:30", r"D:\script\a.bat"),
    ("Task_Bat1210", "12:10", r"D:\script\b.bat"),
    ("Task_Bat1845", "18:45", r"D:\script\c.bat"),
    ("Task_Bat2200", "22:00", r"D:\script\d.bat"),
]

# 批量创建系统定时任务
for task_name, run_time, bat_path in tasks:
    cmd = (
        f'schtasks /create /tn "{task_name}" '
        f'/tr "\"{PYTHON_EXE}\" \"{RUNNER_SCRIPT}\" \"{bat_path}\" '
        f'/sc daily /st {run_time} /rl highest /ru Administrator /f'
    )
    print(f"正在创建任务:{task_name}")
    subprocess.run(cmd, shell=True)

print("\n✅ 所有定时任务创建完成!可通过 taskschd.msc 查看")

4.3 关键最优配置(彻底解决失效问题)

打开 taskschd.msc 打开任务计划程序,对所有任务统一配置:

  • 常规:勾选「不管用户是否登录都要运行」「使用最高权限运行」
  • 条件:取消「仅交流电源运行」「空闲触发」「网络检测」所有多余条件
  • 设置:开启「运行超时自动终止」,任务实例改为「并行运行」,防止卡死阻塞

五、终极避坑总结(必看)

所有脚本、Python、BAT 全部使用绝对路径,杜绝相对路径报错

必须指定工作目录 cwd,解决定时环境路径不匹配问题

所有任务添加超时限制,避免单任务卡死拖累全部任务

开启日志记录,精准区分「任务未触发」和「触发后执行失败」

修改 Windows 密码后,重新保存计划任务凭据

笔记本务必取消电源限制,防止电池模式任务失效

六、方案总结

1. 日常测试、频繁改时间:用 Python Schedule 常驻方案,简单高效、零配置繁琐度;

2. 服务器、长期无人值守、追求稳定:用 Windows 计划任务 + Python 入口方案,彻底根治定时任务间歇性不运行问题,多 BAT 分时段独立执行、互不影响。

到此这篇关于Python实现多BAT文件分时段每日自动执行的文章就介绍到这了,更多相关Python定时执行BAT文件内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Python远程创建docker容器的方法

    Python远程创建docker容器的方法

    这篇文章主要介绍了Python远程创建docker容器的方法,如果docker  ps找不到该容器,可以使用 docker ps -a查看所有的,然后看刚才创建的容器的STATUS是EXIT0还是EXIT1如果是1,那应该是有报错,使用 docker logs 容器id命令来查看日志,根据日志进行解决,需要的朋友可以参考下
    2024-04-04
  • Python代码实现删除一个list里面重复元素的方法

    Python代码实现删除一个list里面重复元素的方法

    今天小编就为大家分享一篇关于Python代码实现删除一个list里面重复元素的方法,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-04-04
  • python类参数self使用示例

    python类参数self使用示例

    python中__new__和__init__到底是怎么一回事,使用方法看下面的代码,大家参考使用吧
    2014-02-02
  • python pyautogui实现图片识别点击失败后重试功能

    python pyautogui实现图片识别点击失败后重试功能

    这篇文章主要介绍了python pyautogui实现图片识别点击失败后重试效果,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧
    2024-06-06
  • python基于win32实现窗口截图

    python基于win32实现窗口截图

    这篇文章主要为大家详细介绍了python基于win32api实现窗口截图,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-03-03
  • Python脚本实现12306火车票查询系统

    Python脚本实现12306火车票查询系统

    本文给大家分享我使用python3实现的12306火车票查询系统,小编分步骤给大家介绍的非常详细,感兴趣的朋友一起看看吧
    2016-09-09
  • 将自己的Python包发布到PyPI上的教程详解

    将自己的Python包发布到PyPI上的教程详解

    在Python中我们经常使用pip来安装第三方Python软件包,其实我们每个人都可以免费地将自己写的Python包发布到PyPI上,本文小编就来教教大家如何将自己的Python包发布到PyPI上吧
    2023-09-09
  • Python的collections模块中的OrderedDict有序字典

    Python的collections模块中的OrderedDict有序字典

    字典是无序的,但是collections的OrderedDict类为我们提供了一个有序的字典结构,名副其实的Ordered+Dict,下面通过两个例子来简单了解下Python的collections模块中的OrderedDict有序字典:
    2016-07-07
  • python函数调用,循环,列表复制实例

    python函数调用,循环,列表复制实例

    这篇文章主要介绍了python函数调用,循环,列表复制实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-05-05
  • Tkinter组件Checkbutton的具体使用

    Tkinter组件Checkbutton的具体使用

    Checkbutton组件用于实现确定是否选择的按钮,本文主要介绍了Tkinter组件Checkbutton的具体使用,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-01-01

最新评论