Laufzeit testen, vergleichen von Laufzeiten verschiedener Skripte mit der Batch RunTimeCalc. Beispielanwendung - Schreibrechte des aktuellen Benutzers testen
Dieser Artikel steht im direktem Zusammenhang zu dem Snippet von bastla im Artikel: "Laufzeit bzw. Dauer einer Batch ermitteln!". Das Skript enstand als Übung zur allgemeinen Einarbeitung in Programiersprachen. Dem nach ist es die Arbeit eines blutigen Anfängers (Programierung) mit der gegebenen Pflicht zur Sorgfalt.
Noch kurz zu mir. Ich stehe bis her nicht nur entfernt zur Fachtermina, sondern auch zu Deutschland. Was meint, das Antworten durchaus etwas mehr Zeit benötigen.
Hallo wertes Forum,
es stand nicht in meiner Absicht einen eigenen Blog zu eröffnen. Wer mehr wissen möchte springt am besten zum oben angegebenen Link und ist schnell im Thema. Ursprünglich wollte ich nicht die vielen Codezeilen in die Menge schmeißen, sondern ein vereinfachtes Ablaufschema und ein paar Zeilen als Antwort posten. Da ich leider keine Möglichkeit gefunden habe, ein Bild in eine Antwort einzubinden, gibt es jetzt alles in einem Rutsch als eigenen Beitrag. Denn ohne eine grafische Darstellung, wird die Einarbeitung in den Code vermutlich etwas anstrengend.
Nur was mache ich jetzt mit dem enstandenen Programm (chen)?
Entsprechend meiner generellen Auffassung gibt man zurück, was man bekommen hat. Als Neuling schreibt man andererseits auch keinen Blog. Doch die Technik läßt keinen anderen Weg und so mache ich diese Erfahrung noch neben bei.
aktualisiert am 27.11.2012
„RunTimeCalc“ läßt mit folgenden Schritten einfach in das Testskript einbauen.
1. Einbindung in die Umgebung des Testskriptes
Wird die Variable %log_file% im Testskript verwendet, schreibt RunTimeCalc bei gesetztem @prozessnamen die Messergebnisse in das Logfile des Testskriptes.
„set RunTimeCalc=...“ setzt die Variable zum Aufruf des Tools. Wird der Computer neu gestartet und RunTimeCalc das erste mal ausgeführt wird manchmal die erste Messung verzögert. Innerhalb der Routine kann dieses nur mit Verlust an Performance verhindert werden. Daher ist der bessere Weg ein blinder Aufruf mit „call“
2. Starten der Messung mit Schalter „-S“
Es sind nur Buchstaben ohne Umlaute, Zahlen und keine Leerzeichen erlaubt.
Jeder Prozess muss einen eindeutigen Namen besitzen
3. Beenden der Messung mit Schalter „-E“
Der Prozessname muss identisch mit dem Namen bei Schalter „-S“ sein.
Hinweis
RunTimeCalc besitzt eine Fehlerroutine und ein Protokollsystem. Fluch und Segen. Der zu testende Code sollte vollständig ausführbar sein. Meldet sich RunTimeCalc mit einem Menü, liegt ein Fehler vor. Der Laufzeitrechner gibt einen Hinweis. RunTimeCalc testet nur Zeit, nicht den Code.
Ablauf
Priorität wie folgt:
1. keine Berechtigung
2. keine Schreibberechtigung
3. keine Schreibberechtigung für aktuellen User
angenehmes Testen wünscht
Viewfinder
Noch kurz zu mir. Ich stehe bis her nicht nur entfernt zur Fachtermina, sondern auch zu Deutschland. Was meint, das Antworten durchaus etwas mehr Zeit benötigen.
Hallo wertes Forum,
es stand nicht in meiner Absicht einen eigenen Blog zu eröffnen. Wer mehr wissen möchte springt am besten zum oben angegebenen Link und ist schnell im Thema. Ursprünglich wollte ich nicht die vielen Codezeilen in die Menge schmeißen, sondern ein vereinfachtes Ablaufschema und ein paar Zeilen als Antwort posten. Da ich leider keine Möglichkeit gefunden habe, ein Bild in eine Antwort einzubinden, gibt es jetzt alles in einem Rutsch als eigenen Beitrag. Denn ohne eine grafische Darstellung, wird die Einarbeitung in den Code vermutlich etwas anstrengend.
Inhaltsverzeichnis
Ursprung
Das Thema liegt schon eine Weile auf Eis, doch ich brauchte einen Einstieg in die Thematik Programiersprache. Bei den deutsch sprachigen Recherchen landet man immer wieder bei Administrator.de. Ob die Batchprogramierung hier der richtige Ansatz ist bleibt fraglich. Auf jeden Fall habe ich einen Einblick bekommen und kann mich ausgereifteren Sprachen zuwenden.Nur was mache ich jetzt mit dem enstandenen Programm (chen)?
Entsprechend meiner generellen Auffassung gibt man zurück, was man bekommen hat. Als Neuling schreibt man andererseits auch keinen Blog. Doch die Technik läßt keinen anderen Weg und so mache ich diese Erfahrung noch neben bei.
History
Bastlas Antwort auf eine Userfrage war ein kompletter Berechnungsmodus den man unter Laufzeit bzw. Dauer einer Batch ermitteln! einsehen kann. Das Skript, für welches die Laufzeit berechnet werden soll (in Folge Laufzeitskript genannt), muss zwischen die Codezeilen gelegt werden.Das Laufzeitskript läuft als Subroutine der Laufzeitberechnung.
Da bastla lediglich eine schnelle Antwort geliefert hat, lag das Laufzeitskript an der logischen Position im Code. Also mitten drinn. Nichts für DAU and me.Die Lage des Laufzeitskriptes ist riskant und nicht ergonomisch.
Damit war schon mal die Aufgabe gefunden.Entwicklung
Gerade als Anfänger tut man sich mit den vielen Begriffen schwer. Bastlas Code brauchte einen Namen RunTimeCalc. Die Ideen häuften sich und so wurde daraus schnell ein Konzept zu einem Tool. Was soll dieses Tool können?- Vergleichszeiten verschiedener Skripte aus der Laufzeit ausgeben (erledigt)
- Zeitmessung und Zeitberechnung als Subroutine ausführen (erledigt)
- Einfache Bedienung mit Fehlerhandling stellen (erledigt)
- Bedienungsfehler ausgeben (erledigt)
- Logsystem integrieren (erledigt)
Aktualisierung
27.11.2012 Hilfe und Protokollierung verbessert, Pause aus „:EXIT“ entfernt (sorry)Ablaufschema.
Tool RunTimeCalc (Code)
:Environment
@echo off
pushd %~dp0
setlocal
:VarTranslate
:: Startvariablen
set "ProcessID=%2"
set "StartParameter=%1"
:: Handling ProcessID
:: ... bei fehlendem Startparameter
if "%StartParameter:~0,1%" EQU "@" (
set "ProcessID=%StartParameter%"
set "StartParameter="
)
:: ... Formatierung
if "%ProcessID:~0,1%" EQU "@" (
set "ProcessID=%ProcessID:~1%"
) else (set "ProcessID=")
:InputControl
FOR %%i in ( [-C] [-E] [-H] [-S]) do IF [%StartParameter%] EQU %%i goto :Settings
echo.
echo RuntimeCalc
echo.
echo --------mistake: [%1]--------------------------------------------------
echo Startzeit [-S] Endzeit, Berechnung[-E] Hilfe [-H] interne Berechnung
echo Kontrolle [-C] ProcessID [@Text_ohne_Leerzeichen]
echo.
echo.
echo "%ProgName%" wurde wegen falschem Parameter beendet.
echo.
echo.
goto :Exit
:Settings
set "ProgName=RunTimeCalc"
set "RTC_FilePath=%~dp0"
set "RTC_InfStamp=%date%;%time%;[INFO];[%ProcessID%]"
set "RTC_ErrStamp=%date%;%time%;[ERROR];[%ProcessID%]"
if "%log_file%" EQU "" set "log_file=%~dp0%ProgName%.log"
:: Abhaengikeit zu ":ActiveProcess" und ":MenuSet1"
set "RTC_ProcFile=%RTC_FilePath%%ProgName%_TEMP_%ProcessID%.cmd"
:StartParameter
:: Handling StartParameter
:: ... IFs ueberspringen
if "%StartParameter%" EQU "" goto :SetStartTime
:: ... Startzeit aus Datei abrufen
if "%StartParameter%" EQU "-E" (
if not exist "%RTC_ProcFile%" goto :Error-E
call :GetTime
call %RTC_ProcFile%
goto :SetEndTime
)
:: ... Startzeit in Datei speichern
if "%StartParameter%" EQU "-S" (
if exist "%RTC_ProcFile%" goto :Error-S
call :GetTime
goto :WriteProcess
)
:: ... Hilfe des Programms aufrufen
if "%StartParameter%" EQU "-H" goto :Help
:: ... laufende Prozesse abfragen
if "%StartParameter%" EQU "-C" goto :Control-C
:SetStartTime
:: Start der Berechnungsroutine
:: ... Startzeit (in Hundertstelsekunden) holen
call :GetTime
:: ... Startzeit in Variablen speichern
set "Startzeit=%t%"
set "Start=%TimeInHSec%"
:: --------------------
:: ... Startet das innenliegende Skript (optional)
call :StartRunTimeSkript
:: --------------------
:SetEndTime
:: Holt die Endzeit und berechnet Differenz zur Startzeit
:: ... Endzeit (in Hundertstelsekunden) holen und in Variablen speichern
call :GetTime
set "Endzeit=%t%"
set "End=%TimeInHSec%"
:Calculator
:: ... Ermittlung und Zerlegung/Formatierung der Differenz
set /a Diff=%End%-%Start%
:: ... Tageswechsel beachten
if %Diff% lss 0 set /a Diff+=8640000
set DiffRem=%Diff%
:: ... Hundertstelsekunden holen
call :GetPart 100
set hs=%Part%
:: ... Sekunden holen
call :GetPart 60
set s=%Part%
:: ... Minuten holen
call :GetPart 60
set m=%Part%
:: ... Stunden bleiben als Rest
set h=%DiffRem%
:Output
:: Ausgabe der Daten, End of Batch
if [%ProcessID%] NEQ (
if not exist "%RTC_ProcFile%" (
echo %RTC_InfStamp%>>%log_file%
echo [%ProcessID%] Startzeit %Startzeit%>>%log_file%
)
echo [%ProcessID%] Endzeit %EndZeit%>>%log_file%
echo [%ProcessID%] Dauer %h%:%m%:%s%,%hs%>>%log_file%
)
echo.
if "%StartParameter%" == "" call :Reference
echo ...............................
echo Laufzeit zum Prozess [%ProcessID%]
echo -------------------------------
echo Startzeit: %Startzeit%
echo Endzeit: %EndZeit%
echo Dauer: %h%:%m%:%s%,%hs%
echo ...............................
echo.
if exist "%RTC_ProcFile%" del %RTC_ProcFile%
goto :Exit
:GetTime
:: Subroutine zur Bildung der Variablen von Start- und End- zeit
:: ... Aktuelle Zeit verwenden ...
set t=%time%
:: ... Systemvariable "time" zerlegen, Formatierungszeichen entfernen ...
for /f "tokens=1-4 delims=:," %%i in ("%t%") do set "h=%%i" & set "m=%%j" & set "s=%%k" & set "hs=%%l"
:: ... Oktalzahlklippen umschiffen ...
if %m:~0,1%==0 set m=%m:~1%
if %s:~0,1%==0 set s=%s:~1%
if %hs:~0,1%==0 set hs=%hs:~1%
:: ... und in Hundertstelsekunden-Wert umrechnen.
set /a TimeInHSec=((%h%*60+%m%)*60+%s%)*100+%hs%
goto :eof
:GetPart
:: Subroutine zur Berechnung der Differenz
:: ... Anhand des Aufrufparameters (60 oder 100) aufspalten ...
set /a Part=%DiffRem%%%%1
:: ... und mit fuehrender Null formatieren sowie ...
if %Part% lss 10 set Part=0%Part%
:: ... noch aufzuteilenden Rest der Differenz ermitteln.
set /a DiffRem=%DiffRem%/%1
goto :eof
:WriteProcess
:: Schreibt "RTC_ProcFile" und speichert Startzeit
echo @echo off>%RTC_ProcFile%
echo TITLE %ProgName% [%ProcessID%]>>%RTC_ProcFile%
:: ... speichern der Variablen als festen Wert
echo set "Startzeit=%t%">>%RTC_ProcFile%
echo set "Start=%TimeInHSec%">>%RTC_ProcFile%
:: ... Protokoll unerwuenscht - schneller machen
echo if [%ProcessID%] EQU ^(goto :eof^)>>%RTC_ProcFile%
:: ... Wertuebergabe an das Protokoll bei Aufruf des "RTC_ProcFile"
echo echo %%RTC_InfStamp%%^>^>%log_file%>>%RTC_ProcFile%
echo echo [%ProcessID%] Startzeit %%Startzeit%%^>^>%log_file%>>%RTC_ProcFile%
echo goto :eof>>%RTC_ProcFile%
echo Startzeit mit "%t%" und ProcessID [%ProcessID%] wurde gespeichert.
goto :Exit
:Error-E
:: Fehlerhandling wenn Prozess nicht vorhanden
set "MessageID=Err-E"
echo.
echo.
echo WARNUNG:
echo ProcessID: [%ProcessID%]
echo Eine Laufzeitberechnung mit gleicher ProcessID wurde nicht gefunden.
echo %RTC_ErrStamp%>>%log_file%
echo [%ProcessID%];%MessageID%;Gleichnamiger Prozess wurde nicht gefunden>>%log_file%
echo [%ProcessID%];%MessageID%;Betroffene Startzeiten werden nachfolgend aufgelistet.>>%log_file%
echo.
echo Der aktuelle Vorgang ist relevant fuer ALLE aktiven Laufzeitberechnungen.
echo Er ist nicht ausfuehrbar und wird in jedem Fall abgebrochen.
echo.
echo Liste der aktiven Laufzeitberechnungen
call :ActiveProcess
echo.
goto :MenuOptionen
:Error-S
:: Fehlerhandling wenn Prozess vorhanden
set "MessageID=Err-S"
echo.
echo.
echo WARNUNG:
echo ProcessID: [%ProcessID%]
echo Eine Laufzeitberechnung mit gleicher ProcessID wurde bereits gestartet
echo und nicht beendet.
echo %RTC_ErrStamp%>>%log_file%
echo [%ProcessID%];%MessageID%;Gleichnamiger Prozess gefunden>>%log_file%
echo [%ProcessID%];%MessageID%;Betroffene Startzeiten werden nachfolgend aufgelistet.>>%log_file%
echo - Jede Laufzeitberechnung die innerhalb einer aktiven Laufzeitberechnung
echo gestartet wird, benoetigt eine eigene ProcessID.
echo.
echo Der aktuelle Vorgang ist relevant fuer ALLE aktiven Laufzeitberechnungen.
echo.
echo Liste der aktiven Laufzeitberechnungen
call :ActiveProcess
echo.
echo Bei Fortsetzung des aktuellen Prozesses wird eine neue Startzeit
echo gespeichert. In der Logdatei erfolgt ein Hinweis auf diesen Vorgang.
echo.
goto :MenuOptionen
:Control-C
:: Zugang zum Menue
set "MessageID=Ctrl-C"
echo.
echo.
echo HINWEIS:
echo ProcessID: [%ProcessID%]
echo Es werden alle gestarteten Prozesse Prozesse angezeigt. Dieser Vorgang
echo wird grundsaetzlich geloggt.
echo %RTC_InfStamp%>>%log_file%
echo [%ProcessID%];%MessageID%;Gleichnamiger Prozess gefunden>>%log_file%
echo [%ProcessID%];%MessageID%;Betroffene Startzeiten werden nachfolgend aufgelistet.>>%log_file%
echo.
echo Liste der aktiven Laufzeitberechnungen
call :ActiveProcess
echo.
goto :MenuOptionen
:ActiveProcess
:: Listet betroffene Prozesse [Startzeiten]
FOR /R %RTC_FilePath% %%I in (%ProgName%_TEMP_*.cmd) do set "RunProzess=%%I"
if "%RunProzess%" == "" (
echo %MessageID%;Es wurden keine laufenden Prozesse gefunden.
echo [%ProcessID%];%MessageID%;Es wurden keine laufenden Prozesse gefunden.>>%log_file%
goto :eof
)
setlocal enabledelayedexpansion
for /R %RTC_FilePath% %%I in (%ProgName%_TEMP_*.cmd) do (
set "RunProzess=%%~nI"
echo %MessageID%;[!RunProzess:%ProgName%_TEMP_=!]
echo [%ProcessID%];%MessageID%;[!RunProzess:%ProgName%_TEMP_=!]>>%log_file%
)
setlocal disabledelayedexpansion
goto :eof
:MenuOptionen
echo.
echo ---------------
echo OPTIONS - MENUE
echo ---------------
echo.
echo Die Optionen koennen durch Eingabe von 1, 2, 3 oder 4 gewaehlt werden
echo -------------------------------------------------------------------------
echo 1. Loeschen aller Startzeiten, %ProgName% beenden (empfohlen) [1]
echo 2. Loeschen der aktuellen Startzeit, %ProgName% beenden [2]
echo aktueller Prozess ist: [%ProcessID%]
echo 3. Fortsetzen von %ProgName% - Ueberschreiben der Startzeit [3]
echo 4. Beenden von %ProgName% [4]
echo.
set /p "input="
if "%input%" EQU "1" set "MenuOption=1" & goto :MenuSet1
if "%input%" EQU "2" set "MenuOption=2" & goto :MenuSet2
if "%input%" EQU "3" set "MenuOption=3" & goto :MenuSet3
if "%input%" EQU "4" set "MenuOption=4" & goto :MenuSet4
echo.
echo --------mistake: [%input%]--------------------------------------------------
echo Incorrect input Select [1] [2] [3] [4]
echo.
echo [%ProcessID%];Eingabefehler - Option nicht vorhanden.>>%log_file%
goto :MenuOptionen
:MenuSet1
if not exist "%RTC_FilePath%%ProgName%_TEMP_*.cmd" (
echo %MessageID%;%MenuOption%;Option steht nicht zur Verpfuegung.
echo [%ProcessID%];%MessageID%;%MenuOption%;Fehleingabe durch Benutzer.>>%log_file%
goto :MenuOptionen
)
setlocal enabledelayedexpansion
for /R %RTC_FilePath% %%I in (%ProgName%_TEMP_*.cmd) do (
set "RunProcess=%%~I"
del %%I
set "ShortName=!RunProcess:%RTC_FilePath%%ProgName%_TEMP_=!"
set "RunProcess=!ShortName:.cmd=!"
echo %MessageID%;%MenuOption%;[!RunProcess!] wurde geloescht.
echo [%ProcessID%];%MessageID%;%MenuOption%;[!RunProcess!] wurde geloescht.>>%log_file%
)
setlocal disabledelayedexpansion
echo %MessageID%;%MenuOption%;%ProgName% wird automatisch beendet.
echo %MessageID%;%MenuOption%;Eintragung der geloeschten Startzeiten in die Logdatei "%log_file%".
echo [%ProcessID%];%MessageID%;%MenuOption%;%ProgName% wurde automatisch beendet.>>%log_file%
goto :Exit
:MenuSet2
if not exist "%RTC_ProcFile%" (
echo %MessageID%;%MenuOption%;Option steht nicht zur Verpfuegung.
echo [%ProcessID%];%MessageID%;%MenuOption%;Fehleingabe durch Benutzer.>>%log_file%
goto :MenuOptionen
)
if exist "%RTC_ProcFile%" (
del %RTC_ProcFile%
echo %MessageID%;%MenuOption%;[%ProcessID%] wurde geloescht.
echo [%ProcessID%];%MessageID%;%MenuOption%;[%ProcessID%] wurde geloescht.>>%log_file%
echo %MessageID%;%MenuOption%;%ProgName% wird automatisch beendet.
echo %MessageID%;%MenuOption%;Eintragung der geloeschten Startzeit in die Logdatei "%log_file%".
echo [%ProcessID%];%MessageID%];%MenuOption%;%ProgName% wurde automatisch beendet.>>%log_file%
goto :Exit
)
:MenuSet3
if not exist "%RTC_ProcFile%" (
echo %MessageID%;%MenuOption%;Option steht nicht zur Verpfuegung.
echo [%ProcessID%];%MessageID%;%MenuOption%;Fehleingabe durch Benutzer.>>%log_file%
goto :MenuOptionen
)
if exist "%RTC_ProcFile%" (
echo %MessageID%;%MenuOption%;%ProgName% wird fortgesetzt und Startzeit ueberschrieben.
echo %MessageID%;%MenuOption%;Eintragung der ueberschriebenen Startzeit in die Logdatei "%log_file%".
echo [%ProcessID%];%MessageID%;%MenuOption%;%ProgName% wird fortgesetzt und Startzeit ueberschrieben.>>%log_file%
call :GetTime
goto :WriteProcess
)
:MenuSet4
echo %MessageID%;%MenuOption%;%ProgName% wird durch Benutzer beendet.
echo %MessageID%;%MenuOption%;Eintragung erfolgt in die Logdatei "%log_file%".
echo [%ProcessID%];%MessageID%;%MenuOption%;%ProgName% wurde durch Benutzer beendet.>>%log_file%
goto :Exit
:Reference
echo.
echo.
echo TIP:
echo Die Batch "%~f0"
echo wurde ohne Startarameter ausgefuehrt. Fuer die Berechnung
echo der Laufzeit wird das Skript INNERHALB der Batch verwendet.
echo -----------------------------------------------------------
echo.
echo.
goto :eof
:Help
echo.
echo.
echo.
echo HILFE:
echo Diese Batch "%ProgName%.cmd" berechnet die Laufzeit eines
echo Skriptes. Wird die Batch ohne Parameter ausgefuehrt,
echo muss sich dieses Skript innerhalb dieser Batch befinden. Der
echo Bereich fuer das Skript ist entsprechend gekennzeichnet.
echo Mit gesetzten Parameter muss diese Batch aus einem externen
echo Skript aufgerufen werden. Der Parameter "-S" speichert die
echo Startzeit in nachfolgender Datei.
echo "%RTC_ProcFile%"
echo Die Batch wird beendet und das zu berechnende Skript laeuft
echo ab. Mit dem Parameter "-E" wird diese Batch wiederholt
echo aufgerufen. Die gespeicherte Startzeit wird ausgelesen,
echo die Laufzeit berechnet und angezeigt. Mit Startparameter wird
echo das Ergebnis in nachfolgender Datei geloggt.
echo "%log_file%"
echo Zum Abschluss wird die Datei mit der Startzeit geloescht.
echo ANMERKUNG:
echo Ist %ProgName% noch nicht geladen, kommt es in einigen Faellen
echo zu unerwarteten Ergebnissen. Ein einfaches
echo call %ProgName%.cmd^>NUL
echo am Anfang des zu messenden Skriptes behebt diese Koriositaet.
echo.
echo.
echo SYNTAX:
echo [Batchname] [-Parameter] [@ProcessID]
echo Batchname = Name der dieser Batch
echo Parameter: -C = Listet Prozesse und stellt ein Menue
echo -E = Beendet Laufzeitzeitberechnung
echo (Startzeit muss gespeichert sein)
echo gilt fuer externes Skript
echo -H = Ruft diese Hilfe auf.
echo -S = Start der Batch (speichert nur die Startzeit)
echo gilt fuer externes Skript
echo ProcessID = Identifikator der Laufzeitberechnung, dient zur
echo Bezeichnung der Logs, darf keine Leerzeichen haben.
echo Ohne ProcessID wird kein Log geschrieben.
echo.
pause
echo.
echo HINWEIS:
echo Grundsaetzlich gilt:
echo - Der Startparameter bestimmt die Verwendung der Batch
echo (externe, interne Berechnung, Hilfe oder Kontrolle)
echo Die ProzessID identifiziert den Prozess und regelt das Log.
echo Die Logdatei befindet sich immer im Verzeichnis dieser Batch.
echo Siehe hierzu die Standardeinstellung:
echo set "log_file=%~dp0%ProgName%.log"
echo
echo - Keine ID - kein Log - keine Mehrfachberechnungen
echo.
echo Diese Batch benoetigt bei externen Aufruf und Fehl- Eingaben
echo Schreibrechte in dem Verzeichis in dem sie ausgefuehrt wird.
echo.
echo Startzeit: -^> Bezeichnet den Anfang der Berechnung
echo Endzeit: -^> Bezeichnet das Ende der Berechnung
echo Dauer: -^> Differenz aus Ende-Anfang
echo.
pause
echo.
echo MEHRFACHBERECHNUNGEN
echo Kreuzungen von Berechnungen sind moeglich. Dabei gilt folgendes:
echo - Jede Laufzeitberechnung die innerhalb einer aktiven Laufzeitberechnung
echo gestartet wird, benoetigt eine eigene ProcessID.
echo - Werden die Laufzeitberechnungen innerhalb eines Skriptes verschachtelt,
echo addiert sich die Abweichung. Ein direkter Vergleich ist nicht mehr objektiv.
echo.
echo Verschachtelung von Berechnungen:
echo -----------------------------------------
echo @echo off
echo echo ...
echo.
echo call %ProgName%.cmd -S @ScriptTime
echo :: Start einer verschachtelten Berechnung
echo echo ...
echo.
echo call %ProgName%.cmd -S @Snippet01
echo :: Laufzeitberechnung "@Snippet01"
echo echo ...
echo call %ProgName%.cmd -E @Snippet01
echo echo ...
echo.
echo call %ProgName%.cmd -S @Snippet02
echo :: vergleichbar mit "@Snippet01"
echo echo ...
echo call %ProgName%.cmd -E @Snippet02
echo echo ...
echo.
echo :: Ende der verschachtelten Berechnung
echo call %ProgName%.cmd -E @ScriptTime
echo goto eof
echo -----------------------------------------
echo.
pause
echo.
echo BEISPIELE:
echo call %ProgName%.cmd -S @time01
echo Startet die Batch aus einer externen Datei mit ID "time01".
echo Setzt den Anfang der Berechnung, speichert "process".
echo.
echo call %ProgName%.cmd -E @time01
echo Startet die Batch aus einer externen Datei mit ID "time01".
echo Berechnet die abgelaufene Zeit und loescht "process".
echo.
echo %ProgName%.cmd -C
echo Listet alle ueber Schalter [-C] angelegten Prozesse und.
echo stellt ein Menue zur Verfuegung. Dieser Vorgang wird
echo grundsaetzlich geloggt
echo.
echo %ProgName%.cmd @time01
echo Startet die Batch von der Konsole mit ID "time01".
echo Berechnet die Laufzeit des IN DER BATCH liegenden Skriptes.
echo Ohne Startparameter wird keine Startzeit gespeichert. Das Log
echo erfolgt erst nach der Berechnung.
echo.
echo %ProgName%.cmd
echo Startet die Batch von der Konsole ohne ID.
echo Berechnet die Laufzeit des IN DER BATCH liegenden Skriptes.
echo Fuehrt die Batch ohne Schreibprozesse aus. Die ermittelten Daten
echo werden auf dem Bildschirm ausgegeben.
echo.
echo.
goto :Exit
:Exit
popd
endlocal
goto :eof
:StartRunTimeSkript
:: Startmarke der Laufzeitberechnung
:: ... Skriptbereich optional
::----------------------------------------------------
REM Skriptbereich zum Testen der Laufzeit
::----------------------------------------------------
:: beendet Laufzeitskript als Subroutine
:: ... Der nachfolgende Befehl darf nicht entfernt werden.
goto :eof
Anwendung
Immer wenn es nicht zügig vorangeht wird geschraubt, gestöpselt, aufgerüstet und weniger in den Code geschaut. Manchmal sind es einfach nur Zeilenumbrüche oder missratene Datenausgaben. Zum Vergleichen des Codes mit Alternativen, bedarf es Werkzeuge. Zwei davon sind ein Laufzeitrechner und eine Routine zur Berechnung der Schleifen. Beide sind im Anwendungsbeispiel enthalten.„RunTimeCalc“ läßt mit folgenden Schritten einfach in das Testskript einbauen.
1. Einbindung in die Umgebung des Testskriptes
set "log_file=%~dp0%~n0.log"
set „RunTimeCalc=Drive:\Path zu RunTimeCalc“
call %RunTimeCalc%>NUL
„set RunTimeCalc=...“ setzt die Variable zum Aufruf des Tools. Wird der Computer neu gestartet und RunTimeCalc das erste mal ausgeführt wird manchmal die erste Messung verzögert. Innerhalb der Routine kann dieses nur mit Verlust an Performance verhindert werden. Daher ist der bessere Weg ein blinder Aufruf mit „call“
2. Starten der Messung mit Schalter „-S“
call %RunTimeCalc% -S @Name-des-Prozesses
Jeder Prozess muss einen eindeutigen Namen besitzen
3. Beenden der Messung mit Schalter „-E“
call %RunTimeCalc% -E @Name-des-Prozesses
Hinweis
RunTimeCalc besitzt eine Fehlerroutine und ein Protokollsystem. Fluch und Segen. Der zu testende Code sollte vollständig ausführbar sein. Meldet sich RunTimeCalc mit einem Menü, liegt ein Fehler vor. Der Laufzeitrechner gibt einen Hinweis. RunTimeCalc testet nur Zeit, nicht den Code.
Anwendungsbeispiel
Es kommt der Tag, da zählt nur das kleinste Gemeinsame zwischen Windows. Bislang ist das noch cmd.exe.Schreibrechte prüfen
Es sollen die Schreibrechte des aktuellen Users im Arbeitsverzeichnis rekursiv ermittelt werden. Ein hervorragendes Beispiel zum Einsatz einer Laufzeitberechnung. Diese soll helfen, performanten Code zu finden. Bei Vergleichen zwischen den Ausgaben von „icacls“ und „whoami“ spielt dieses Thema keine Rolle. Der schlichte Entwurf endet in einer Kathastrophe irgendwo zwischen Unix und Microsoft. Die Beispieldatei, beinhaltet den Entwurf und dessen Ueberarbeitung sowie die gesamte VergleichsroutinePermWrite
Sucht nach Schreibberechtigung des angemeldeten Benutzers an Dateien und Verzeichnissen, gibt bei erfolgloser Suche eine Ziel-weisende Mitteilung aus und bei Versagen eine Fehlermeldung.Ablauf
- Speichert den angemeldeten User und seine Relationen (Zugehoerigkeit) in eine Listen-Variable
- Gibt alle erreichbaren Verzeichnisse rekursiv und Dateien aus
- Liest Dateiberechtigungen aus
- Formatiert „LF“ zu „CR LF“
- Formatiert Datenbrei
- Filtert nach Schreibberechtigung
- Vergleicht „icacls“- Ausgabe mit Listen-Variable
- Trefferanzahl kann mit interaktiven Match- Counter gesteuert werden
- Fehlermeldungen werden nach Priorität ausgegeben
Priorität wie folgt:
1. keine Berechtigung
2. keine Schreibberechtigung
3. keine Schreibberechtigung für aktuellen User
PermFile
Ablauf- Gibt alle Dateien aus Verzeichnissen mit Berechtigung aus
- Verarbeitet gefundene Dateien mit "icacls"
- Ermittelt den angemeldeten User und seine Relationen (Zugehoerigkeit)
- Vergleicht Ausgaben von "icacls" und "whoami"
- Erzeugt Fehlermeldung bei fehlenden Schreibrechten
Anwendungsbeispiel "PermWrite" Vergleich "PermFile" (Code)
:Environment
@echo off
setlocal
pushd %~dp0
setlocal enabledelayedexpansion
set "file_path=F:\Public\Projects\WWW\testbasis\Test"
set "log_file=%~dp0%~n0.log"
set "TimeStamp=%date%;%time%"
:Tools
set "RunTimeCalc=F:\Public\Projects\WWW\testbasis\script-local\runtime\RunTimeCalc.cmd"
call %RunTimeCalc%>NUL
:Routine
call :PermWrite
call :Entwurf
:EXIT
setlocal disabledelayedexpansion
popd
endlocal
goto :eof
:PermWrite
echo.
echo ================================================================================
echo PermWrite V01 - Schreibrechte des aktuellen Users an Verzeichnis, Datei pruefen
echo ================================================================================
call %RunTimeCalc% -S @PermWrite-V01
for /f "delims=, tokens=1,2" %%a in ('whoami /user /fo csv /nh') do (
set /a USERab+=1
set ID_User=%%a,USER,%%b
set ID_User=!ID_User:"=!
)
set "NamesList="
for /f "delims=, tokens=1" %%c in ('echo !ID_User!^& whoami /groups /fo csv /nh') do (
set /a NAMEcd+=1
set Names=%%c
set Names=!Names:"=!
set NamesList=!NamesList!#!Names!#;
)
echo.
echo %USERDOMAIN%\%USERNAME% - bitte warten. Die Routine arbeitet ...
echo.
:: Trefferanzahl n+1; nicht fuer normale "for %%I"
set match=
for /f "tokens=*" %%a in ('dir %file_path% /b /s') do (
set /a N_a+=1
set Match_d=
set Warn=
set set Prot_b=& set Prot_c=& set Prot_d=
set Prot_a=a
for /f "tokens=* usebackq" %%b in (`icacls "%%a"`) do (
set /a N_b+=1
if "!Match_d!" LEQ "!match!" (
set B=%%b
set B=!B:%%a =!
set B=!B:^(=[!
set B=!B:^)=]!
if "%%b" EQU "%%a " set Warn=b
set Prot_b=b
for /f "delims=:" %%c in ('echo !B!^|findstr /E /L "F] M] W]"') do (
set /a N_c+=1
set Prot_c=c
for /f "tokens=*" %%d in ('echo %NamesList%^|Findstr /I /C:"#%%c#"') do (
set /a N_d+=1
set /a Match_d+=1
::echo %%c
set Prot_d=d
)
)
)
)
if "!Prot_b!" NEQ "b" (
echo ERRROR;Error;"icacls" Abfrage nicht moeglich mit "...\%%~nxa".
echo %TimeStamp%;ERRROR;Error;"icacls" Abfrage nicht moeglich mit "%%a".>>%log_file%
)
if "!Warn!" EQU "b" (
echo NOTICE;Warn;Keine Rechte definiert fuer "...\%%~nxa".
echo %TimeStamp%;NOTICE;Warn;Keine Rechte definiert fuer "%%a".>>%log_file%
)
if "-!Prot_b!-!Warn!-!Prot_c!-!Prot_d!-" EQU "-b----" (
echo NOTICE;Warn;Kein Schreibzugriff definiert auf "...\%%~nxa".
echo %TimeStamp%;NOTICE;Warn;Kein Schreibzugriff definiert auf "%%a".>>%log_file%
)
if "-!Prot_b!-!Warn!-!Prot_c!-!Prot_d!-" EQU "-b--c--" (
echo NOTICE;Tip;USER "%USERNAME%" besitzt keine Schreibrechte an "...\%%~nxa".
echo %TimeStamp%;NOTICE;Tip;USER "%USERNAME%" besitzt keine Schreibrechte an "%%a".>>%log_file%
)
)
if "!Prot_a!" EQU "" (
echo ERROR;Error;:PermWrite kann nicht ausgefuehrt werden.
echo ERROR;Tip;Pruefen "icacls", "whoami" oder "%file_path%".
echo %TimeStamp%;ERROR;Error;:PermWrite kann nicht ausgefuehrt werden.>>%log_file%
echo %TimeStamp%;ERROR;Tip;Pruefen "icacls", "whoami" oder "%file_path%".>>%log_file%
)
echo.
echo %N_a% Dateien und Verzeichnisse geprueft.
call %RunTimeCalc% -E @PermWrite-V01
for %%I in (N_a N_b N_c N_d) do (
if "!%%I!" EQU "" set %%I=0
set /a Schleifenzahl+=!%%I!
)
echo.
echo Dateien, Verzeichnisse ^= %N_a%^|Tokens Rechte ^= %N_b%^|Schreibrechte ^= %N_c%^|Uebereinstimmung ^= %N_d%
echo Schleifenzahl gesamt ^= %Schleifenzahl%
goto :eof
::###########################################
:Entwurf
echo.
echo ================================================================================
echo PermFile ENTWURF Schreibrechte des aktuellen Users an Datei pruefen
echo Kurz, uebersichtlich, langsam und falsch
echo ================================================================================
call %RunTimeCalc% -S @Entwurf-PermFile
for /r %file_path%\ %%Z in ("*") do (
set /a FOR_Z+=1
set stop=
for /f "tokens=* usebackq" %%a in (`icacls "%%Z"`) do (
set /a FOR_a+=1
for /f %%b in ('whoami /user /groups /fo table /nh') do (
if "!stop!" NEQ "s" (
set /a FOR_b+=1
for /f "tokens=*" %%c in ('echo %%a^|findstr /e "F) M) W)"^|findstr /i "%%b"') do (
set /a FOR_c+=1
set stop=s
))
)
)
if "!stop!" EQU "" echo USER "%USERNAME%" besitzt keine Schreibrechte an "...\%%~nxZ".
)
echo.
echo %FOR_Z% Dateien geprueft.
call %RunTimeCalc% -E @Entwurf-PermFile
for %%I in (FOR_Z FOR_a FOR_b FOR_c) do (
if "!%%I!" EQU "" set %%I=0
set /a Schleifenzahl_E+=!%%I!
)
echo.
echo Dateien ^= %FOR_Z%^|Datei Rechte ^= %FOR_a%^|Namen ^= %FOR_b%^|Uebereinstimmung ^= %FOR_c%
echo Schleifenzahl gesamt ^= %Schleifenzahl_E%
goto :eof
angenehmes Testen wünscht
Viewfinder
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 188502
Url: https://administrator.de/contentid/188502
Ausgedruckt am: 08.11.2024 um 15:11 Uhr