简体   繁体   中英

Variable not working inside an if statement when used in a for loop with enabledelayedexpansion

I have a text file with MS Windows update names:

...
KB3072019
KB3044374
KB3011780
KB3083711
...

And having a folder with

下载的更新

:

My goal is to check wether an update is downloaded or not according to the text file.

@echo off
set /a x=0
setlocal ENABLEDELAYEDEXPANSION

for /F "tokens=*" %%A in (d:\WindowsUpdate.log) do (
set /a x=x+1
echo Update number !x!, name %%A, state:
IF EXIST d:\!Del\Win8Updates_x64\Merged\*%%A*.cab (echo Downloaded) ELSE (echo MISSING!)
)
pause

The output should be like this:

Update number 83, name KB3045999, state:
MISSING
Update number 84, name KB3045746, state:
Downloaded
Update number 85, name KB3066441, state:
Downloaded
Update number 86, name KB3071663, state:
MISSING

But actually it looks like this:

Update number 83, name KB3045999, state:
MISSING
Update number 84, name KB3045746, state:
MISSING
Update number 85, name KB3066441, state:
MISSING
Update number 86, name KB3071663, state:
MISSING

My question: why does %%A not work inside the if statement?

Important: I don't want to skip the line numbers, because they're representing the order of the updates. Later I'll modify the script to copy/move the existing updates to another location prefixed with it's order number, like 83_windows8.1-kb3045999-x64.cab

There is a path containing an exclamation mark, d:\\!Del , which causes the problem, because when delayed expansion is enabled, the ! is removed. This is also true for the echoed text MISSING! . Removing @echo off temporarily will allow you to see that behaviour when examining the output.

To avoid that, there are (at least) the following options:

  1. Escaping exclamation marks:

     @echo off set /A x=0 setlocal EnableDelayedExpansion for /F "tokens=*" %%A in (d:\\WindowsUpdate.log) do ( set /A x+=1 echo Update number !x!, name %%A, state: if exist "d:\\^!Del\\Win8Updates_x64\\Merged\\*%%A*.cab" ( echo Downloaded ) else ( echo MISSING^^! ) ) endlocal pause 
  2. Disabling delayed expansion temporarily:

     @echo off set /A x=0 setlocal EnableDelayedExpansion for /F "tokens=*" %%A in (d:\\WindowsUpdate.log) do ( set /A x+=1 echo Update number !x!, name %%A, state: setlocal DisableDelayedExpansion if exist "d:\\!Del\\Win8Updates_x64\\Merged\\*%%A*.cab" ( echo Downloaded ) else ( echo MISSING! ) endlocal ) endlocal pause 
  3. Enabling delayed expansion only where needed:

     @echo off set /A x=0 setlocal DisableDelayedExpansion for /F "tokens=*" %%A in (d:\\WindowsUpdate.log) do ( set /A x+=1 setlocal EnableDelayedExpansion echo Update number !x!, name %%A, state: endlocal if exist "d:\\!Del\\Win8Updates_x64\\Merged\\*%%A*.cab" ( echo Downloaded ) else ( echo MISSING! ) ) endlocal pause 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM