time - por - echo off bat
¿Cuánto demora ejecutar un archivo por lotes? (6)
Esto es algo tangencial, pero puede ayudarte.
Microsoft tiene un programa timeit.exe que funciona más o menos como una versión mejorada del comando ''tiempo'' de Unix. Viene en el Kit de recursos de Windows Server 2003 , y prácticamente ha reemplazado todas las veces que he querido hacer algo como lo que estás sugiriendo.
Puede valer la pena mirar.
¿Cómo puedo escribir un script para calcular el tiempo que tardó el script en completarse?
Pensé que este sería el caso, pero obviamente no ...
@echo off
set starttime=%time%
set endtime=%time%
REM do stuff here
set /a runtime=%endtime%-%starttime%
echo Script took %runtime% to complete
Mi preferencia personal es instalar Cygwin y usar el comando de time
pero, si realmente tiene que hacerlo como un archivo por lotes, no puede simplemente restar las cadenas, debe tratarlas como partes.
La siguiente secuencia de comandos sincronizará un comando de ping de 10 segundos con la capacidad de cruzar un límite de un solo día sin quedar atrapado en números negativos. Una ligera mejora le permitiría cruzar muchos límites de un día.
@echo off
setlocal enableextensions enabledelayedexpansion
set starttime=%time%
ping -n 11 127.0.0.1 >nul: 2>nul:
set endtime=%time%
set /a hrs=%endtime:~0,2%
set /a hrs=%hrs%-%starttime:~0,2%
set /a mins=%endtime:~3,2%
set /a mins=%mins%-%starttime:~3,2%
set /a secs=%endtime:~6,2%
set /a secs=%secs%-%starttime:~6,2%
if %secs% lss 0 (
set /a secs=!secs!+60
set /a mins=!mins!-1
)
if %mins% lss 0 (
set /a mins=!mins!+60
set /a hrs=!hrs!-1
)
if %hrs% lss 0 (
set /a hrs=!hrs!+24
)
set /a tot=%secs%+%mins%*60+%hrs%*3600
echo End = %endtime%
echo Start = %starttime%
echo Hours = %hrs%
echo Minutes = %mins%
echo Seconds = %secs%
echo Total = %tot%
endlocal
No se puede hacer aritmética de tiempo directamente en scripts por lotes, por lo que necesitará un programa externo para calcular la diferencia de tiempo, o extraer cada parte del tiempo y hacer aritmética de esa manera.
Eche un vistazo al final de este hilo del foro para ver un ejemplo de cómo hacer esto último.
También asumo que es un error tipográfico, pero debes asegurarte de configurar el tiempo de finalización después del procesamiento.
Echa un vistazo a esta secuencia de comandos que recuperará el tiempo a través de WMI por lo que es independiente de configuración regional.
@echo off
::::::::::::::::::::::::::::::::::::::::::
:: TimeDiff v1.00 by LEVENTE ROG ::
:: www.thesysadminhimself.com ::
::::::::::::::::::::::::::::::::::::::::::
::[ EULA ]:::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Feel free to use this script. The code can be redistributed ::
:: and edited, but please keep the credits. ::
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::[ CHANGELOG ]::::::::::::::
:: v1.00 - First Version ::
:::::::::::::::::::::::::::::
FOR /F "skip=1 tokens=1-6" %%A IN (''WMIC Path Win32_LocalTime Get Day^,Hour^,Minute^,Second /Format:table ^| findstr /r "."'') DO (
set Milisecond=%time:~9,2%
set Day=%%A
set Hour=%%B
set Minute=%%C
set Second=%%D
)
set /a Start=%Day%*8640000+%Hour%*360000+%Minute%*6000+%Second%*100+%Milisecond%
::
::
:: PUT COMMANDS HERE
ping www.thesysadminhimself.com
::
::
FOR /F "skip=1 tokens=1-6" %%A IN (''WMIC Path Win32_LocalTime Get Day^,Hour^,Minute^,Second /Format:table ^| findstr /r "."'') DO (
set Day=%%A
set Hour=%%B
set Minute=%%C
set Second=%%D
)
set Milisecond=%time:~9,2%
set /a End=%Day%*8640000+%Hour%*360000+%Minute%*6000+%Second%*100+%Milisecond%
set /a Diff=%End%-%Start%
set /a DiffMS=%Diff%%%100
set /a Diff=(%Diff%-%DiffMS%)/100
set /a DiffSec=%Diff%%%60
set /a Diff=(%Diff%-%Diff%%%60)/60
set /a DiffMin=%Diff%%%60
set /a Diff=(%Diff%-%Diff%%%60)/60
set /a DiffHrs=%Diff%
:: format with leading zeroes
if %DiffMS% LSS 10 set DiffMS=0%DiffMS!%
if %DiffSec% LSS 10 set DiffMS=0%DiffSec%
if %DiffMin% LSS 10 set DiffMS=0%DiffMin%
if %DiffHrs% LSS 10 set DiffMS=0%DiffHrs%
echo %DiffHrs%:%DiffMin%:%DiffSec%.%DiffMS%
Dos cosas saltan sobre el archivo por lotes original. pero ninguno va a ayudar en el largo plazo.
Sea cual sea su método de referencia, asegúrese de capturar el tiempo de inicio antes de la operación y el tiempo de finalización después de la operación. Tu muestra no hace eso.
%time%
evalúa algo así como "12: 34: 56.78", y el comandoSET /A
no puede restar esos. Necesita un comando que produzca una marca de tiempo escalar simple.
Iba a decir que no se puede hacer, pero el lenguaje por lotes es mucho más poderoso de lo que se le atribuye, así que aquí hay una implementación simple de TIMER.BAT. Para el registro, Pax me dio una respuesta que mostraba la división de cuerdas mientras yo estaba jugueteando, y Johannes Rössel sugirió mover la aritmética fuera de la región medida:
@echo off
setlocal
rem Remeber start time. Note that we don''t look at the date, so this
rem calculation won''t work right if the program run spans local midnight.
set t0=%time: =0%
rem do something here.... but probably with more care about quoting.
rem specifically, odd things will happen if any arguments contain
rem precent signs or carets and there may be no way to prevent it.
%*
rem Capture the end time before doing anything else
set t=%time: =0%
rem make t0 into a scaler in 100ths of a second, being careful not
rem to let SET/A misinterpret 08 and 09 as octal
set /a h=1%t0:~0,2%-100
set /a m=1%t0:~3,2%-100
set /a s=1%t0:~6,2%-100
set /a c=1%t0:~9,2%-100
set /a starttime = %h% * 360000 + %m% * 6000 + 100 * %s% + %c%
rem make t into a scaler in 100ths of a second
set /a h=1%t:~0,2%-100
set /a m=1%t:~3,2%-100
set /a s=1%t:~6,2%-100
set /a c=1%t:~9,2%-100
set /a endtime = %h% * 360000 + %m% * 6000 + 100 * %s% + %c%
rem runtime in 100ths is now just end - start
set /a runtime = %endtime% - %starttime%
set runtime = %s%.%c%
echo Started at %t0%
echo Ran for %runtime%0 ms
Puede simplificar la aritmética y ser un poco más honesto sobre la precisión general de esto al no molestarse con las centésimas de una segunda parte. Aquí está en acción, suponiendo que tienes un comando de suspensión o alguna otra pérdida de tiempo:
C:> TIMER SLEEP 3
Script took 3000 ms to complete
C:>
Editar: revisé el código y su descripción como se sugiere en un comentario.
Creo que cuando el equipo de NT reemplazó COMMAND.COM con CMD.EXE, pensaron que no se saldría con la tarea de hacerlo muy diferente. Pero, en efecto, es casi un lenguaje completamente nuevo. Muchos de los viejos comandos favoritos tienen nuevas características si las extensiones están habilitadas.
Uno de ellos es SETLOCAL
que evita que las variables modifiquen el entorno de la persona que llama. Otro es SET /A
que le proporciona una gran cantidad de aritmética. El truco principal que he usado aquí es la nueva sintaxis de extracción de subcadenas donde %t:~3,2%
significa los dos caracteres que comienzan en el desplazamiento 3 en el valor de la variable llamada t
.
Para una sorpresa real, eche un vistazo a la descripción completa del conjunto (intente SET /?
En un aviso) y si eso no lo asusta, busque FOR /?
y observe que puede analizar texto de archivos ...
Edición 2: corrigió el mal manejo de los campos de tiempo que contenían 08
o 09
reportados por Frankie en los comentarios. Pellizcó un par de cosas y agregó algunos comentarios.
Tenga en cuenta que hay una deslumbrante descuido que probablemente no voy a solucionar. No funcionará si el comando comienza en un día diferente de lo que termina. Es decir, hará algunas matemáticas relacionadas con la hora del día e informará una diferencia, pero la diferencia no significará mucho.
Repararlo para al menos advertir sobre este caso es fácil. Repararlo para hacer lo correcto es más difícil.
Edición 3: error solucionado donde el% h% no está configurado correctamente para horas de un solo dígito. Esto se debe a%% return% "9: 01: 23.45". Observe el espacio. Usar% time: = 0% reemplaza el espacio con un cero inicial y% h% se establecerá correctamente. Este error solo ocurrió cuando un script se ejecutó de una hora a la siguiente.
Excelente pequeña rutina. Sin embargo, si el cálculo abarca dos días, el cálculo es incorrecto. El resultado debe restar de 24 horas (8640000 centiseconds).
También elimine uno de los comandos duplicados ''set'' en la línea correspondiente.
Tenga en cuenta que las configuraciones regionales afectan el formato de la función TIME, siendo el decimal un tope en el Reino Unido en lugar de una coma.
Las líneas
rem podríamos haber medido el tiempo entre los días
if %ENDTIME% LSS %STARTTIME% set set /A DURATION=%STARTTIME%-%ENDTIME%
necesita cambiar a
rem podríamos haber medido el tiempo en días
if %ENDTIME% LSS %STARTTIME% set /A DURATION=8640000 - (%STARTTIME% - %ENDTIME%)