Эта проблема вызвана классическим отложенным расширением перехвата каждого новичка при записи командного файла, который никогда не читал справку команды SET при запуске в окне командной строки set /?
.
Блок команд, начинающийся с (
и заканчивающийся соответствием )
, анализируется командным процессором Windows до выполнения команды, использующей этот блок команд.Во время синтаксического анализа командного блока все вхождения %variable%
заменяются текущими значениями указанных переменных среды.Это можно увидеть при отладке командного файла .
См. Также Как интерпретатор сценариев команд Windows (CMD.EXE) анализирует?
Итак, вэтот случай %size%
заменяется ничем, поскольку эта переменная среды, скорее всего, не существует при выполнении командного файла до выполнения команды IF , которая проверяет наличие файла журнала.Определение переменной среды size
внутри блока команд в реально существующем файле журнала не вступает в силу для %size%
, уже замененного пустой строкой на этапе синтаксического анализа блока команд.
Наиболее вероятное лучшее решение в этомдело избегает всех командных блоков.Тогда отсроченное расширение переменной среды также не требуется.
@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "LogFile=%~dpn0.log"
set "MaxLogFileSize=4000"
if not exist "%LogFile%" echo Do Nothing>>"%LogFile%"& goto DoMore
for %%I in ("%LogFile%") do set "LogFileSize=%%~zI"
if %LogFileSize% LSS %MaxLogFileSize% goto DoMore
for /F "tokens=2 delims==." %%I in ('%SystemRoot%\System32\wbem\wmic.exe OS GET LocalDateTime /VALUE') do set "TimeStamp=%%I"
set "FileTimeStamp=%TimeStamp:~0,4%-%TimeStamp:~4,2%-%TimeStamp:~6,2%_%TimeStamp:~8,2%-%TimeStamp:~10,2%-%TimeStamp:~12,2%"
set "TextTimeStamp=%TimeStamp:~0,4%-%TimeStamp:~4,2%-%TimeStamp:~6,2% %TimeStamp:~8,2%:%TimeStamp:~10,2%:%TimeStamp:~12,2%"
move /Y "%LogFile%" "%~dpn0_%FileTimeStamp%.log"
>"%LogFile%" echo Time stamp: %TextTimeStamp%
>>"%LogFile%" echo Old log: %~n0_%FileTimeStamp%.log
:DoMore
rem Add here more command lines using "%LogFile%".
endlocal
На мой взгляд, не очень хорошая идея ограничивать размер файла журнала и дополнительно держать файл журнала на превышении лимита с файломимя, содержащее текущую местную дату и время.Это приводит к тому, что на носителе появляется все больше и больше файлов журнала, а ограничение размера файла журнала не мешает использовать все больше и больше места для хранения.
Было бы лучше просто переместить и без того слишком большой файл журнала с фиксированным файлом.имя перезаписывает уже существующий файл с таким именем.
Пример:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "LogFile=%~dpn0.log"
set "MaxLogFileSize=4000"
set "OldLogFile=%~dpn0_old.log"
if exist "%LogFile%" for %%I in ("%LogFile%") do if %%~zI GTR %MaxLogFileSize% move /Y "%LogFile%" "%OldLogFile%"
rem Add here more command lines using "%LogFile%".
endlocal
Пакетный файл перезаписывает файл *_old.log
текущим файлом журнала с превышением лимита файла журнала.Таким образом, текущий файл журнала содержит зарегистрированную информацию о последних действиях, а файл *_old.log
содержит архивную зарегистрированную информацию, записанную в течение определенного периода времени, в зависимости от того, сколько информации регистрируется при каждом выполнении пакетного файла и как часто выполняется пакетный файл.в течение определенного промежутка времени.Максимальное когда-либо необходимое место для хранения составляет примерно вдвое значение MaxLogFileSize
, и никто больше не должен периодически удалять старые файлы журналов, которые никто больше не просматривал.
Примечание: Командный процессор Windows использует32-разрядная целочисленная арифметика со знаком.Таким образом, значение MaxLogFileSize
должно быть на достаточное количество байт ниже максимального положительного 32-разрядного целого числа со знаком, равного 2 GiB или 2147483647 в байтах, чтобы предотвратить то, что текущий файл журнала станет больше или равен 2147483648 байтов.
Чтобы понять используемые команды и то, как они работают, откройте окно командной строки, выполните там следующие команды и полностью прочитайте все страницы справки, отображаемые для каждой команды.
call /?
... объясняет %~dpn0
, который расширяется до диска, пути и имени пакетного файла без расширения файла. echo /?
endlocal /?
for /?
goto /?
if /?
move /?
rem /?
set /?
setlocal /?
wmic /?
wmic os /?
wmic os get /?
wmic os get localdatetime /?
Я также рекомендую прочитать: