Reputation: 453
Given the following code:
@Echo off
ECHO Start
ECHO Calling SUB_A
CALL :SUB_A
ECHO Calling SUB_B
CALL :SUB_B
:SUB_A
ECHO In SUB_A
GOTO:EOF
:SUB_B
ECHO In SUB_B
GOTO:EOF
ECHO End
I expect this output:
Start
Calling SUB_A
In SUB_A
Calling SUB_B
In SUB_B
End
But I get this:
Start
Calling SUB_A
In SUB_A
Calling SUB_B
In SUB_B
In SUB_A
What am I doing wrong here?
Upvotes: 45
Views: 81978
Reputation: 85
Do not use EXIT!
Example:
@rem a.bat
@echo off
echo a.bat
timeout /t 1
call b.bat
call c.bat
@rem b.bat
@echo off
echo b.bat
timeout /t 1
call :subB
rem call to c.bat will fail if using "exit" instead of "goto :end"
goto :end
:subB
echo subB
timeout /t 1
exit /b
:end
@rem c.bat
@echo off
echo c.bat
timeout /t 1
"exit" immediately aborts the call chain!
Upvotes: 0
Reputation: 1467
Just to stick my $0.02 worth in here:
I would have to say that DOS files (or DOS batch files) should always be written as :
[ Main Program ]
EXIT
[ All Subroutines ]
In this way - you can never fall into the subroutine section.
Also - always use REM statements before, during, and possibly after each section so you always know what a section is going to do.
And last - but not least - See if you can write a batch file so it becomes more generic so you can set it to one side and use it when you need to again.
Just my $0.02 worth of common sense you probably already know. :-)
OH! Sorry! Forgot to post my small sleeper subroutine I wrote. Here it is! :-)
REM
REM Calling the Sleeper subroutine
REM
call :sleeper
exit
REM
REM Sleeper subroutine
REM
REM qna = Questions and Answers
REM
REM Interestingly - you can NOT use a '>'
REM Because DOS uses it for redirection!
REM Instead - use a question mark (?)
REM
:sleeper
set /p qna=Press return to continue or 'q' to stop ?
if [%qna%] == [q] (
echo Exiting....please wait.
exit
)
goto :eof
Upvotes: 4
Reputation: 3983
If you want to return from a CALL, you use EXIT command with /B argument (as "EXIT" alone will terminate the batch file).
For example:
CALL :SUB_ONE
CALL :SUB_TWO
GOTO :EOF
:SUB_ONE
ECHO Hello from one
EXIT /B
:SUB_TWO
ECHO Hello from two
EXIT /B
:EOF
Upvotes: 76
Reputation: 10809
The line CALL :SUB_B
returns, the script proceeds to the next few lines:
:SUB_A # no effect from this one
ECHO In SUB_A # prints message
You need to insert a GOTO:EOF
after the call if you want it to stop there.
Batch files are not structured programs; they are a sequence of instructions with some BASIC-like facility for GOTO and CALL.
Upvotes: 22
Reputation: 11489
After your line CALL :SUB_B
the batch file falls through to SUB_A. If you don't want it to, you need to put a GOTO
line there.
Upvotes: 6