Adriano Araujo
Adriano Araujo

Reputation: 29

%errorlevel% returning 0 in loop command

Ok, I've installed Dropbox but it didn't corresponded to what I was looking for so I uninstalled it with Revo Pro. But, when i open the taskmanager there are still processes related to it running in my computer so I decided to make a batch to look out and delete all files that are related to it.

    @echo off
    cd c:\
    :a
    set /p a=Phrase that might be realted to it 

    for /r %%d IN (*.*) DO (
        (
        findstr /i /m /c:%a% "%%d"
        if "%errorlevel%"=="0" del "%%d"
        echo %errorlevel%
        )
    )

    pause

The problem is: when I run findstr using loop even when there is no match for my variable "%a%" in an analized file %errorlevel% returns as 0. But when I use findstr alone and there isn't a match %ERRORLEVEL% returns as 1 and 0 for a match. If I use it, I'll delete all my PC files haha. What's wrong with the code?

Upvotes: 1

Views: 2589

Answers (3)

Mofi
Mofi

Reputation: 49096

Whenever Windows command interpreter encounters ( being interpreted as begin of a command block, it parses the entire command block up to matching ) marking end of the command block and replaces all %variable% by current value of the variable.

This means in this case that before command FOR is the first time executed, everything from ( after DO up to last ) is processed already with replacing all %variable% references by current value of the appropriate variable. Then the already preprocessed block is executed one (on command IF) or more times (on command FOR).

This behavior can be seen by debugging the batch file. For debugging a batch file first @echo off must be removed or commented out with command REM or changed to @echo on. Then a command prompt window must be opened and the batch file is executed from within this command prompt window by typing its name with full path enclosed in double quotes if path or name contains a space character. The Windows command interpreter shows now all command lines and command blocks after preprocessing before executing and of course the standard messages and the error messages output by the commands or by Windows command interpreter itself in case of a syntax error in batch file.

Opening a command prompt window means running cmd.exe with option /K to Keep window open after execution of a command or a batch script. Double clicking on a batch file starts also cmd.exe for processing the batch file, but with parameter /C to Close the window automatically after batch processing terminated independent on cause - successful finished or an error occurred.

The command prompt window opened before running the batch file remains open after batch processing finished successfully or with an error except the batch file contains command EXIT without parameter /B. So experts in batch code writing test batch files always by running them from within a command prompt window instead of double clicking on them.

Delayed variable expansion is needed for variables set or modified and referenced within same command block as explained by help of command SET output on running in a command prompt window set /?.

@echo off
setlocal EnableDelayedExpansion
cd /D C:\
:a
set /P "a=Phrase that might be realted to it: "

for /r %%d in (*) do (
    %SystemRoot%\System32\findstr.exe /i /m /c:"%a%" "%%d"
    if "!errorlevel!" == "0" del "%%d" >nul
)
endlocal

But for checking the exit code of a previous command there is also if errorlevel syntax as explained by Microsoft in support article Testing for a Specific Error Level in Batch Files.

@echo off
setlocal EnableDelayedExpansion
cd /D C:\
:a
set /P "a=Phrase that might be realted to it: "

for /r %%d in (*) do (
    %SystemRoot%\System32\findstr.exe /i /m /c:"%a%" "%%d" >nul
    if not errorlevel 1 del "%%d" >nul
)
endlocal

if errorlevel X tests if exit code of previous command or application when it modifies the errorlevel variable at all is greater or equal X. By using if not errorlevel X the check is if last exit code is lower than X which is here a test if exit code is 0.

For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.

  • cd /?
  • del /?
  • echo /?
  • for /?
  • if /?
  • set /?

And see also

Upvotes: 0

galra
galra

Reputation: 385

Not sure what's wrong with the code, but you can probably skip it using the && operand.

 findstr /i /m /c:%a% "%%d" && del "%%d" echo %errorlevel%

Thanks to Stephan for correcting the example.

Upvotes: 0

Magoo
Magoo

Reputation: 80023

Within a parenthesised series of statements, any %var% is replaced by the value of that variable at the time the verb controlling that statement-sequence (or block) is encountered.

Here, the block is the entire sequence of statements controlled by the for. %errorlevel% is replaced by the status of errorlevel at the time the for is encountered, so probably 0.

If you use

    findstr /i /m /c:%a% "%%d"
    if not errorlevel 1 del "%%d"
    echo %errorlevel%

then the run-time value of errorlevel is used (ie. as it changes through the operation of the loop) and the command means "if errorlevel is not (1 or greater than 1) do this..."

The findstr will set errorlevel to 0 on found, 1 on not found and 2 for file not found(IIRC) so NOT (1 or greater than 1) selects 0 only. Note that in certain esoteric circumstances, errorlevel may become negative, but after a findstr I believe 0..2 is the allowed range.

Upvotes: 2

Related Questions