2009-04-11 7 views
17

Wie kann ich ein Skript schreiben, um die Zeit zu berechnen, die das Skript benötigt hat?Wie lange dauert die Ausführung einer Batch-Datei?

dachte ich, das wäre der Fall sein, aber offensichtlich nicht ..

@echo off 
set starttime=%time% 
set endtime=%time% 

REM do stuff here 

set /a runtime=%endtime%-%starttime% 
echo Script took %runtime% to complete 
+1

shouldn‘ test du die Endzeit, nachdem du etwas getan hast? ist es ein Tippfehler? –

+0

Nun, Sie könnten einfach "Zeit ./myscript" – mpen

+0

@mark, in einem Lager Windows-Installation, Zeit ist ein Befehl in CMD.EXE eingebaut, der die aktuelle Uhrzeit setzt oder anzeigt. – RBerteig

Antwort

1

Sie keine Zeit Arithmetik direkt im Batch-Scripting tun kann, so dass Sie entweder Sie ein externes Programm brauchen die Zeitdifferenz zu berechnen , oder extrahiere jeden Teil der Zeit und führe die Arithmetik so aus.

Werfen Sie einen Blick auf die Unterseite von this forum thread für ein Beispiel für die letztere.

Ich nehme auch an, es ist ein Tippfehler, aber Sie wollen sicher sein, endtimenach Verarbeitung einzustellen.

2

Meine persönliche Präferenz ist Cygwin zu installieren und verwenden, um die time Befehl aber, wenn Sie tatsächlich haben es als Batch-Datei zu tun, können Sie nicht abziehen nur die Saiten, müssen Sie sie als Teile behandeln.

Das folgende Skript wird einen 10-Sekunden-Ping-Befehl mit der Fähigkeit, eine einzelne Taggrenze zu überschreiten, ohne in negative Zahlen gebunden zu werden. Eine leichte Verbesserung würde es erlauben, viele Tagesgrenzen zu überschreiten.

@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 
4

Dies ist irgendwie tangential, aber es kann Ihnen helfen.

Microsoft hat ein Programm "timeit.exe", das mehr oder weniger wie eine verbesserte Version des Unix-Befehls "time" funktioniert. Es kommt in der Windows Server 2003 Resource Kit, und es hat ziemlich viel ersetzt alle Zeiten, die ich wollte etwas tun, was Sie vorschlagen.

Es kann einen Blick wert sein.

35

Zwei Dinge springen über die ursprüngliche Batch-Datei. , aber beides wird auf lange Sicht nicht helfen.

  1. Was auch immer Ihre Benchmark-Methode, müssen Sie die Startzeit vor den Betrieb und die Endzeit nach der Betrieb zu erfassen. Ihre Probe tut das nicht.

  2. %time% ergibt etwas wie "12: 34: 56.78", und der SET /A Befehl kann diese nicht subtrahieren. Sie benötigen einen Befehl, der einen einfachen skalaren Zeitstempel erzeugt.

Ich wollte es nicht getan werden sagen können, aber die Batch-Sprache ist viel mächtiger als es so hier Kredit für, gegeben ist, ist eine einfache Implementierung von TIMER.BAT. Für die Aufzeichnung schlug Pax mich auf eine Antwort die Zeichenfolge Spaltung zeigt, während ich um hantiere, und Johannes Rössel schlug die Arithmetik außerhalb des gemessenen Bereichs bewegt:

@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 

Sie können die Arithmetik vereinfachen und eine wenig mehr sein ehrlich über die Gesamtgenauigkeit davon, nicht mit den 100. eines zweiten Teils zu belästigen.Hier ist es in Aktion, vorausgesetzt, Sie haben einen Schlafbefehl oder eine andere Zeit Waster:

C:> TIMER SLEEP 3 
Script took 3000 ms to complete 
C:> 

Edit: ich den Code und seine Beschreibung überarbeitet wie in einem Kommentar vorgeschlagen.

Ich denke, dass, wenn das NT-Team COMMAND.COM mit CMD.EXE ersetzte, sie dachten, sie würden nicht damit durchkommen, es sehr anders zu machen. Aber in Wirklichkeit ist es fast eine völlig neue Sprache. Viele der alten Favoritenbefehle haben neue Funktionen, wenn die Erweiterungen aktiviert sind.

Eine davon ist SETLOCAL, die verhindert, dass Variablen die Umgebung des Anrufers ändern. Ein anderer ist SET /A, der Ihnen eine bemerkenswerte Menge an Arithmetik bietet. Der Haupttrick, den ich hier verwendet habe, ist die neue Zeichenkettenextraktionssyntax, wobei %t:~3,2% die zwei Zeichen bedeutet, die bei Offset 3 im Wert der Variablen t beginnen.

Für einen echten Schocker, werfen Sie einen Blick auf die vollständige Beschreibung der Satz (versuchen SET /? an einer Eingabeaufforderung), und wenn das nicht abschreckt, Blick auf FOR /? und feststellen, dass es sich um Text aus Dateien analysieren kann ...

Edit 2: Festfehlbedienung von Zeitfeldern enthalten 08 oder 09 von Frankie in den Kommentaren berichtet. Tweaked ein paar Dinge und fügte einige Kommentare hinzu.

Beachten Sie, dass hier eine grelle Aufsicht herrscht, die ich wahrscheinlich nicht beheben werde. Es wird nicht funktionieren, wenn der Befehl an einem anderen Tag als am Ende beginnt. Das heißt, es wird etwas Mathe bezogen auf die Tageszeit und einen Unterschied berichten, aber der Unterschied wird nicht viel bedeuten.

Fixing es zumindest warnen über diesen Fall ist einfach. Es zu reparieren, um das Richtige zu tun, ist schwieriger.

Bearbeiten 3: Fehler behoben, bei dem% h% nicht für einstellige Stunden eingestellt ist. Dies liegt daran, dass% time% "9: 01: 23.45" zurückgibt. Beachten Sie das Leerzeichen. Mit% time: = 0% wird das Leerzeichen durch eine führende Null ersetzt und% h% wird korrekt gesetzt. Dieser Fehler trat nur auf, wenn ein Skript von einer einstelligen Stunde zur nächsten lief.

+0

+1 für die zusätzliche Meile ... können Sie erklären Das Set/a-Geschäft (derzeit zu Linux gestartet) – ojblass

+0

set/a führt die Arithmetik in Batch aus. Was er hier macht, ist alles auf 1/100 Sekunde zu reduzieren. Danach können Sie sie einfach subtrahieren, da sie beide nur Zahlen sind. – Joey

+0

Vielleicht möchten Sie die ganze Mathematik nach der Ausführung Ihres Befehls tun, obwohl ... Mathe in cmd nicht genau schnell ist, also speichern Sie einfach die Startzeit und fiedeln Sie damit, nachdem Ihr Befehl beendet wurde, damit es nicht gezählt wird die Zeit des Befehls. Weiß nicht, ob es einen Unterschied macht, anscheinend nicht – Joey

2

Schauen Sie sich dieses Skript an, das die Zeit über WMI abruft, sodass es regional unabhängig ist.

@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% 
+0

+1 nette Lösung, aber es ist langsam, jeder Zeitstempel benötigt ~ 100ms-200ms (auf meinem PC 2.4GHz Core2 Duo) – jeb

3

Ausgezeichnete kleine Routine. Wenn sich die Berechnung jedoch über zwei Tage erstreckt, ist die Berechnung falsch. Das Ergebnis muss von 24 Stunden subtrahiert werden (8640000 Centiseconds).

Entfernen Sie auch einen der doppelten "set" -Befehle in der entsprechenden Zeile.

Beachten Sie, dass regionale Einstellungen das Format der TIME-Funktion beeinflussen, wobei die Dezimalstelle ein Vollstop in Großbritannien ist und nicht ein Komma.

Die Linien

rem wir die Zeit dazwischen Tage haben könnte

if %ENDTIME% LSS %STARTTIME% set set /A DURATION=%STARTTIME%-%ENDTIME% 

Notwendigkeit

rem Wechsel maßen wir die Zeit über Tage gemessen haben könnte

if %ENDTIME% LSS %STARTTIME% set /A DURATION=8640000 - (%STARTTIME% - %ENDTIME%)