What's wrong with Windows bat recursion?

I am trying to write windows command commands. Here is my test function:

@echo off & setlocal EnableDelayedExpansion

echo hi

call :minus 1
echo %result%
call :minus 2
echo %result%
call :minus 3
echo %result%
call :minus 4
echo %result%
call :minus 5
echo %result%

PAUSE
goto :eof

:minus
setlocal

set num=%1
if %num% equ 1 endlocal & set result=%num% & goto :eof

set /a num=%num%-1
call :minus %num%

endlocal
goto :eof

      

As expected, for everything greater than and equal to 1, the result will be 1:

hi
1
1
1
1
1
Press any key to continue . . .

      

But when I change the first call to call :minus 2

(the rest is the same):

echo hi

call :minus 2
echo %result%
call :minus 2
echo %result%
call :minus 3
echo %result%
call :minus 4
echo %result%
call :minus 5
echo %result%

PAUSE
goto :eof

      

Output:

hi
ECHO is off.
ECHO is off.
ECHO is off.
ECHO is off.
ECHO is off.
Press any key to continue . . .

      

What does it mean ECHO is off.

?

+3


source to share


3 answers


Well, if you call minus

with 2, it result

will never be set ( if %num% equ 1

will not evaluate to true), so you call echo

without any parameters, which will result in ECHO is off.

both output from @echo off

at the top of your script.



+1


source


The problem lies in endlocal

the end. After going to the same line, ending the local scope before calling recursion, it now works fine:



@echo off & setlocal EnableDelayedExpansion

echo hi

call :minus 1
echo %result%
call :minus 2
echo %result%
call :minus 3
echo %result%
call :minus 4
echo %result%
call :minus 5
echo %result%

PAUSE
goto :eof

:minus
setlocal

set num=%1
if %num% equ 1 endlocal & set result=%num% & goto :eof

set /a num=%num%-1
endlocal & call :minus %num%

goto :eof

      

+1


source


You have a number of problems going on there. An easy way to see what's going on is to put the echo instruction ECHO (% ~ 1 at the beginning of the sub: minus. Then you will see that you are in trouble because you have a SETLOCAL statement in the recursive sub. Short ... you execute SETLOCAL once for each recursion, but only for ENDLOCAL only for the initial call.

In your case, the simplest solution is to get rid of ALL setlocal and endlocal operators. I would move the echo to a subroutine instead of repeating it for every call.

By the way, you don't need EnableDelayedExpansion with your implementation.

Your best bet is to use ECHO (% Variable% instead of ECHO% Variable%). The reason is that if the variable is undefined, the ECHO statement is the same as simply typing ECHO. Try this ... it displays echo (on or off) Lots of people use ECHO or ECHO: you can read everything here http://www.dostips.com/forum/viewtopic.php?f=3&t=1900

0


source







All Articles