penny.cilin
Goto Top

Verständnisfrage Setlocal ENABLEDELAYEDEXPANSION und Zeit

Hallo an die Batchspezialisten unter Euch,

ich habe momentan ein Verständnisproblem mit Setlocal ENABLEDELAYEDEXPANSION und TIME.
Ich definiere ein Variable TIMESTAMP. Diese setzt das Format der Uhrzeit.
Set Timestamp=%TIME:~-11,2%.%TIME:~-8,2%.%TIME:~-5,2%,%TIME:~-0,2%
Soweit so gut.

Der Beginn und das Ende des Batchskriptes soll dokumentiert werden. Zwecks Test werden die Zeiten derzeit auf einem Testsystem auf STDOUT (Bildschirm) ausgegeben.
Deshalb die Codezeilen zum testen.
Später soll das in eine Logdatei geschrieben werden. Das ist nicht das Problem.

Eventuell habe ich einen Denk- / Logikfehlerfehler.
Frage: Wie kann man das Problem mit Startzeit / Endzeit besser lösen?

Das Logging in eine Datei ist nicht das Problem, sondern der TIMESTAMP.

Hintergrund: Es laufen verschiedene Scheduled Task, welche Batchdateien aufrufen.
Hier sollen nun die Start- / Endzeiten der Batches und innerhalb der Batches die Start-/Endezeiten und einzelne Schritten von aufgerufenen Programmen dokumentiert werden.


Variante 1 funktioniert nicht:
@Echo OFF %debug%
    Setlocal ENABLEDELAYEDEXPANSION

    Set Timestamp=%TIME:~-11,2%.%TIME:~-8,2%.%TIME:~-5,2%,%TIME:~-0,2%
    Set Timestamp=%Timestamp: =0%

    echo Startzeit %Timestamp%

    REM Kontollzeit via Aufruf Time
    echo Startzeit %time%

REM Dient zum testen von Laufzeiten
    >NUL DIR %windir% /-p
    >NUL DIR %windir%\system /-p
    >NUL DIR %windir%\system32 /-p
    >NUL DIR %windir%\SoftwareDistribution /-p
    >NUL DIR D:\Data\downloads /-p

    echo.

    echo Endzeit !Timestamp!

    REM Kontollzeit via Aufruf Time
    echo Endeeit %time%

    exit /b 0

Variante 2 funktioniert:
@Echo OFF %debug%
    Setlocal ENABLEDELAYEDEXPANSION

    Set Timestamp=%TIME:~-11,2%.%TIME:~-8,2%.%TIME:~-5,2%,%TIME:~-0,2%
    Set Timestamp=%Timestamp: =0%

    echo Startzeit %Timestamp%

    REM Kontollzeit via Aufruf Time
    echo Startzeit %time%

REM Dient zum testen von Laufzeiten
    >NUL DIR %windir% /-p
    >NUL DIR %windir%\system /-p
    >NUL DIR %windir%\system32 /-p
    >NUL DIR %windir%\SoftwareDistribution /-p
    >NUL DIR D:\Data\downloads /-p

    echo.

    Set Timestamp=%TIME:~-11,2%.%TIME:~-8,2%.%TIME:~-5,2%,%TIME:~-0,2%
    Set Timestamp=%Timestamp: =0%

    echo Endzeit %Timestamp%

    REM Kontollzeit via Aufruf Time
    echo Endeeit %time%

    exit /b 0

Betriebssystems wo die Scheduled Tasks ausgeführt werden:
Windows Server 2008, 2008 R2, 2012, 2012 R2, 2012 und nachfolgende.

Ich kann mir denken bastla, Biber, colinardo und rubberman und andere Batchspezialisten haben bestimmt eine Lösung.

Zum Schluß: PowerShell ist nicht die Lösung, weil die Scheduled Tasks sind bereits als Batchdateien im Einsatz und sollen bleiben.
Da die Hersteller das sonst nicht unterstützen (supporten).

Vielen Dank für Eure Hilfe und Lösungsvorschäge.

Gruss Penny.

Content-ID: 1451914725

Url: https://administrator.de/contentid/1451914725

Ausgedruckt am: 22.11.2024 um 09:11 Uhr

Pjordorf
Pjordorf 31.10.2021 um 17:54:52 Uhr
Goto Top
Hallo,

Zitat von @Penny.Cilin:
Variante 1 funktioniert nicht:
Hättest du die Güte auch deine Fehlermeldung oder genau was nicht funktioniert uns mitzuteilen?

Da die Hersteller das sonst nicht unterstützen (supporten).
Warum sollten sie? Ist doch deins...

Gruß,
Peter
Penny.Cilin
Penny.Cilin 31.10.2021 um 18:24:14 Uhr
Goto Top
@Pjordorf
Danke für Deine Rückmeldung und der berechtigten Nachfrage.

Bei Variante 1 werden folgende Zeiten eingetragen:
Startzeit 18.17.10,18
Startzeit 18:17:10,22

##red|Endzeit 18.17.10,18##
Endeeit 18:17:13,01
Man beachte jeweils die oberen Start- und Endezeiten. Diese sind identisch.

Bei Variante 2 sind die Laufzeiten ich Sie erreichen will:
Startzeit 18.15.38,18
Startzeit 18:15:38,93

Endzeit 18.15.41,18
Endeeit 18:15:41,92

Ich hoffe es wird jetzt verständlicher.

Zitat von @Pjordorf:

Warum sollten sie? Ist doch deins...
Die batchfiles werden von mir um das Logging erweitert. Das ist mit den Herstellern abgestimmt.

Gruß,
Peter

Gruss Penny.
Pjordorf
Lösung Pjordorf 31.10.2021 um 18:42:12 Uhr
Goto Top
Hallo,

Zitat von @Penny.Cilin:
Man beachte jeweils die oberen Start- und Endezeiten. Diese sind identisch.
Deine Variabel Timestamp hat noch alte Werte. Aktualisieren oder getrennte für Start und Stop nutzen. In deiner Variante 2 machst du es richtig. Timestamp ist keine Uhr die weiterläuft, nur ein Platzhalter. Warum sollte eine Variabel mit Name Name und den Wert Ich plötzlich aus Ich Du machen?

Gruß,
Peter
rubberman
Lösung rubberman 31.10.2021 aktualisiert um 22:52:11 Uhr
Goto Top
Hehe. Erst mal EnableDelayedExpansion hat nix mit dem Problem zu tun, bzw. löst es nicht.

%date% und %time% (und %errorlevel% und ein paar mehr) sind dynamische Variablen, keine Umgebungsvariablen. Siehe auch https://ss64.com/nt/syntax-variables.html
Auf deren Wert lässt sich aber auch mit den umschließenden Prozentzeichen zugreifen, so dass es den Anschein erweckt, es wären Umgebungsvariablen. Tatsächlich werden sie aber durch den cmd.exe Prozess aktualisiert. (Sie lassen sich durch Umgebungsvariablen gleichem Namens überschreiben, im Sinne vom englischen "override", woraufhin ihr Wert nicht mehr automatisch aktualisiert wird. Aber das nur nebenher.)
Solltest du nun eine Umgebungsvariable foo mit dem derzeitigen Wert von %time% definieren, dann wird dieser Wert natürlich nicht aktualisiert. Für den cmd.exe Prozess ist foo eine Umgebungsvariable wie jede andere. Also keine automatische Variable, die aktualisiert wird. Sie behält ihren Wert, es sei denn er wird irgendwann durch SET überschrieben.

Delayed Expansion, aka verzögerte Variablenerweiterung, hat einen ganz anderen Sinn. Die cmd.exe expandiert Variablen innerhalb einer Kommandozeile, oder innerhalb eines in Klammern gesetzten Blocks von Kommandozeilen, nur einmal zu ihrem Wert. Und zwar noch im Parse-Prozess, vor der Ausfürung der Zeile / des Blocks. Um diese frühzeitige Expansion zu vermeiden und auch in der Zeile / im Block upgedatete Werte abgreifbar zu machen, kann man mit verzögerter Variablenerweiterung arbeiten, verbunden mit der geänderten Syntax (Ausrufe- statt Prozentzeichen).

// EDIT Ach ja, die Lösung des Problemchens ist natürlich eine Subroutine die dir deine Timestamp Variable aktualisiert.
@echo off &setlocal
call :updateTimestamp
echo %Timestamp%

timeout /t 3

call :updateTimestamp
echo %Timestamp%
pause
exit /b


:updateTimestamp
for /f %%i in ('WMIC OS Get LocalDateTime /value') do for /f %%j in ("%%i") do set "%%j"  
set "Timestamp=%LocalDateTime:~8,2%.%LocalDateTime:~10,2%.%LocalDateTime:~12,2%,%LocalDateTime:~15,2%"  
exit /b
Nutzt WMIC weil es einen Wert liefert, dessen Format nicht von lokalen Settings abhängig ist.

Steffen
Penny.Cilin
Penny.Cilin 01.11.2021 um 09:03:25 Uhr
Goto Top
Danke an @Pjordorf und @rubbermann

Das Verwenden mit einer Subroutine, hört sich gut an.

Gruss Penny.