Reputation: 29
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
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
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
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