Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rotating a log based on certain size into a date/time-stamped copy [duplicate]

It so happens that there is a BAT file running a certain command line tool on a Windows server 2008 and redirects output to an ever-growing log that I want to rotate every time it outgrows certain size. It would be time and effort consuming to change that BAT file into a CMD, needless to say PowerShell PS1. So I am constrained to editing that BAT file.

Everything below is being tested on Windows 7 and 2008.

Tried the following:

for %%I in (Log.txt) do @echo %%~zI >> size.tmp
set /p logSIZE=<size.tmp
del size.tmp
if %logSIZE% GTR 100 (
  echo OK
)

the test Log.txt was 157 bytes at that time and so it echoed OK. Then I did a negative test by increasing 100 to 200 and it did not echo OK. So far so good.

Next I tried to concatenate date and time stamps into the a file name:

For /f "tokens=2-4 delims=/ " %%a in ('date /t') do (set dateStamp=%%c-%%a-%%b)
For /f "tokens=1-2 delims=/:" %%a in ("%TIME%") do (set timeStamp=%%a%%b)
echo Log_%dateStamp%_%timeStamp%.txt

and that worked like a charm too. Next step is to combine both scripts into one:

for %%I in (Log.txt) do @echo %%~zI >> size.tmp
set /p logSIZE=<size.tmp
del size.tmp
if %logSIZE% GTR 100 (
  For /f "tokens=2-4 delims=/ " %%a in ('date /t') do (set dateStamp=%%c-%%a-%%b)
  For /f "tokens=1-2 delims=/:" %%a in ("%TIME%") do (set timeStamp=%%a%%b)
echo %dateStamp%
echo %timeStamp%
  rem move Log.txt "Log%dateStamp%_%timeStamp%.txt"
)

but that no longer worked, as despite the script visibly entering the if block and executing the set commands with the current date/time values, the environment variables remain blank. The echo commands do not output anything and the new file name consists of only Log__.txt.

I tried to debug this by adding the following lines at the beginning of the file:

set dateStamp=A
set timeStamp=B
echo %dateStamp%
echo %timeStamp%

for %%I in (Log.txt) do @echo %%~zI >> size.tmp
set /p logSIZE=<size.tmp
del size.tmp
if %logSIZE% GTR 100 (
  For /f "tokens=2-4 delims=/ " %%a in ('date /t') do (set dateStamp=%%c-%%a-%%b)
  For /f "tokens=1-2 delims=/:" %%a in ("%TIME%") do (set timeStamp=%%a%%b)
echo %dateStamp%
echo %timeStamp%
  rem move Log.txt "Log%dateStamp%_%timeStamp%.txt"
)

that worked correctly, assigning A and B to the variables, but then those values were not re-assigned the date and time stamps within the if block.

I know how to work around that by keeping the environment variable assignment outside the if block:

for %%I in (Log.txt) do @echo %%~zI >> size.tmp
set /p logSIZE=<size.tmp
del size.tmp

For /f "tokens=2-4 delims=/ " %%a in ('date /t') do (set dateStamp=%%c-%%a-%%b)
For /f "tokens=1-2 delims=/:" %%a in ("%TIME%") do (set timeStamp=%%a%%b)

if %logSIZE% GTR 100 (
    echo Log_%dateStamp%_%timeStamp%.txt
)

but still want to get to the bottom of it in case in the future I would have to assign variables inside an if block.

What am I doing wrong?

like image 956
ajeh Avatar asked Jun 23 '16 19:06

ajeh


1 Answers

Posting this, so this question at least had a answer that others can quickly catch, as I did not see the actual answer in the comments. @ths should repost to receive the credit.

As @ths pointed out in the question's comment, the script needs setlocal EnableDelayedExpansion at the beginning to correct the behavior.

You can read more about it from this previous question on the same subject.
windows batch SET inside IF not working

like image 58
John C Avatar answered Oct 15 '22 02:10

John C