我有以下批处理脚本(稍微简化)来并行运行一系列 exe 文件。
SETLOCAL ENABLEDELAYEDEXPANSION
for %%a in (1 2 4 8) do (
set i=%%a
set script=calculate_V!i!.exe
start echo started V!i! at !time:~0,5! ^>^> log.txt ^2^>^&^1
^& !script! ^& echo ended V!i! at !time:~0,5! ^>^> log.txt ^2^>^&^1 ^& exit
)
我想获取脚本运行的开始和结束时间,但问题是第二次的延迟扩展(echoendedV!i!at!time:~0,5!)与第一次同时进行,因此输出为(例如)
started V1 at 15:50
started V2 at 15:50
...
ended V1 at 15:50
ended V2 at 15:50
...
即使脚本需要 10 分钟才能运行。
如何仅在脚本运行后评估 !time:~0,5!?
谢谢
答案1
我已经看过这个了,让它工作的唯一方法是确保时间查找在不同的行上,如果不使用两个批处理文件,我就无法做到这一点。
我已经用timeout /t
它来替代运行一项需要特定时间的任务。
启动器.cmd:-
@echo off
echo.
echo %time% start %1 >>logfile.txt
timeout /t %1 2>&1 1>nul:
echo %time% end %1 >>logfile.txt
exit
调度程序.cmd:-
@echo off
start /b launcher 5
start /b launcher 10
日志文件.txt:-
20:24:01.15 start 5
20:24:01.22 start 10
20:24:06.20 end 5
20:24:11.19 end 10
根据您的目的调整这些文件应该很简单。
笔记:-
start /b
cmd
阻止打开多个窗口;或者,start /min
将使用单独的窗口,但不会有太多的视觉干扰。- 因为
time
是volatile变量,所以不需要使用延迟扩展。 - 如果计划任务是 Windows(不是命令行)程序,
launcher
则需要使用 来start /wait
运行它。 - 确保
exit
启动器线程终止。
答案2
此脚本相当于@AFH的解决方案,但使用了 trampoline 技术。
这使得在同一批处理文件中的标签处启动子进程成为可能。
此外,它还等待两个任务的结束。
我从 dbenham 的帖子中借用了等待技巧等待并行批处理脚本
@echo off
REM *** This is a trampoline to jump to a function when a child process shall be invoked
for /F "tokens=3 delims=:" %%L in ("%~0") do goto %%L
:scheduler
set "lock=%temp%\wait%random%.lock"
:: Launch one and two asynchronously, with stream 9 redirected to a lock file.
:: The lock file will remain locked until the script ends.
:: The batch file calls itself by using %~dpnx0, but hides the label name into the full path
start "title" /b call "%~d0\:launcher:\..%~pnx0" "timeout /t 5" 9>"%lock%1"
start "title" /b call "%~d0\:launcher:\..%~pnx0" "timeout /t 10" 9>"%lock%2"
:Wait for both scripts to finish (wait until lock files are no longer locked)
1>nul 2>nul ping /n 2 ::1
for %%N in (1 2) do (
( rem
) 9>"%lock%%%N" || goto :Wait
) 2>nul
::delete the lock files
del "%lock%*"
exit /b
:launcher
echo Launched "%~1"
echo %time% start "%~1" >>logfile.txt
REM *** Execute the command, it's in the first argument
%~1
echo %time% end "%~1" >>logfile.txt
echo End of "%~1"
exit