软件吧
登录注册账号
/posts/log-clean-bat-windows
电脑必备

把自动优化脚本改成手动触发后,我反而发现计划任务里两个坑

极客阿凯 81 0 13

之前我写过一篇关于计划任务挂自动优化脚本跑三天对账的帖子,结论是自动优化适合懒人,但我自己更爱手动控制。这周我把脚本从定时触发改成了手动触发,顺便把执行逻辑重构了一遍,结果在计划任务本身里踩到两个坑,跟脚本逻辑无关,纯环境问题,记录一下。

背景:脚本干的事很简单,每天凌晨清临时文件、回收站超30天的、顺手压缩几个日志目录。之前用计划任务定时跑,最近改成手动双击触发,跑完自己看一眼日志。

坑一:手动触发时工作目录不是脚本所在目录

我脚本里用了相对路径 log\clean.log 写日志。定时任务跑的时候没毛病,因为任务属性里「起始于」我填了脚本目录。但手动双击 .bat 的时候,工作目录是 bat 所在目录没错,可我用的是快捷方式放到桌面,快捷方式的「起始位置」是空的,结果日志全写到 C:\Windows\System32 下面去了,第一次跑完翻半天没找到日志。

验证:拿两台机子对账,一台用快捷方式触发,一台直接双击 bat,日志路径确实不一样。结论是脚本里凡是涉及路径的全改成绝对路径,或者开头先 cd /d %~dp0,别指望工作目录。

坑二:手动触发时任务计划程序里的「上次运行结果」不刷新

这个坑有点迷惑。我把脚本挂在计划任务里,但改成「仅手动触发」,然后从任务计划程序右键「运行」来启动。跑完去看「上次运行结果」,一直是 0x41301(任务正在运行),其实脚本早结束了。查了一下,是因为脚本里有个后台进程没完全退出,任务计划程序认为任务还挂着。

排查过程:任务管理器里看进程,发现脚本调用的压缩工具在后台留了个子进程,主脚本 exit 了它还在。任务计划程序以父进程退出为准,但子进程没退,状态就卡住。后来在脚本末尾加了 taskkill /f /im 压缩工具.exe 兜底,再跑就正常刷新成 0x0 了。

另外一个小观察:手动触发模式下,任务计划程序的「如果任务已在运行,则」这个选项默认是「不启动新实例」,但手动右键运行不受这个限制,可以并发跑多个实例。我测试的时候手快点了两次,两个实例同时清同一个目录,差点把正在写的日志文件锁死。所以脚本里最好自己加个锁文件判断。

总结一下我这边的改动:

  • 脚本开头统一 cd /d %~dp0,所有路径用绝对路径
  • 末尾加子进程清理,避免任务状态卡住
  • 加了个简单的锁文件,防止手动并发

自动优化那套确实省心,但手动触发的好处是每次跑完能立刻看日志、对结果,出了问题当场就能定位。我现在的用法是:日常清理手动跑,只有那些「跑完不用管」的才挂定时。

问一下各位:你们挂计划任务的时候,有没有遇到过「上次运行结果」一直不刷新的情况?除了子进程没退,还有别的原因吗?我目前只排查到这一个,想多收集几个案例。

登录后可以为帖子点赞,但本帖内容对所有人开放阅读。

社区回应

0 Replies

还没有回应,抢一个沙发。

登录后可以回应和点赞,但本帖内容对所有人开放阅读。