I have a simple function written to check for directories:
:direxist
if not exist %~1 (
echo %~1 could not be found, check to make sure your location is correct.
goto:end
) else (
echo %~1 is a real directory
goto:eof
)
:end is written as
:end
endlocal
I don't understand why the program would not stop after goto:end has been called. I have another function that uses the same method to stop the program and it work fine.
:PRINT_USAGE
echo Usage:
echo ------
echo <file usage information>
goto:end
In this instance, the program is stopped after calling :end; why would this not work in :direxist? Thank you for your help!
I suppose you are mixing call and goto statements here.
A label in a batch file can be used with a call or a goto, but the behaviour is different.
If you call such a function it will return when the function reached the end of the file or an explicit exit /b or goto :eof (like your goto :end).
Therefore you can't cancel your batch if you use a label as a function.
However, goto to a label, will not return to the caller.
Using a synatx error:
But there is also a way to exit the batch from a function.
You can create a syntax error, this forces the batch to stop.
But it has the side effect, that the local (setlocal) variables will not be removed.
#echo off
call :label hello
call :label stop
echo Never returns
exit /b
:label
echo %1
if "%1"=="stop" goto :halt
exit /b
:halt
call :haltHelper 2> nul
:haltHelper
()
exit /b
Using CTRL-C:
Creating an errorcode similar to the CTRL-C errorcode stops also the batch processing.
After the exit, the setlocal state is clean!
See #dbenham's answer Exit batch script from inside a function
Using advanced exception handling:
This is the most powerful solutions, as it's able to remove an arbitrary amount of stack levels, it can be used to exit only the current batch file and also to show the stack trace.
It uses the fact, that (goto), without arguments, removes one element from the stack.
See Does Windows batch support exception handling?
jeb's solution works great. But it may not be appropriate in all circumstances. It has 2 potential drawbacks:
1) The syntax error will halt all batch processing. So if a batch script called your script, and your script is halted with the syntax error, then control is not returned to the caller. That might be bad.
2) Normally there is an implicit ENDLOCAL for every SETLOCAL when batch processing terminates. But the fatal syntax error terminates batch processing without the implicit ENDLOCAL! This can have nasty consequences :-( See my DosTips post SETLOCAL continues after batch termination! for more information.
Update 2015-03-20 See https://stackoverflow.com/a/25474648/1012053 for a clean way to immediately terminate all batch processing.
The other way to halt a batch file within a function is to use the EXIT command, which will exit the command shell entirely. But a little creative use of CMD can make it useful for solving the problem.
#echo off
if "%~1" equ "_GO_" goto :main
cmd /c ^""%~f0" _GO_ %*^"
exit /b
:main
call :label hello
call :label stop
echo Never returns
exit /b
:label
echo %1
if "%1"=="stop" exit
exit /b
I've got both my version named "daveExit.bat" and jeb's version named "jebExit.bat" on my PC.
I then test them using this batch script
#echo off
echo before calling %1
call %1
echo returned from %1
And here are the results
>test jebExit
before calling jebExit
hello
stop
>test daveExit
before calling daveExit
hello
stop
returned from daveExit
>
One potential disadvantage of the EXIT solution is that changes to the environment are not preserved. That can be partially solved by writing the environent to a temporary file before exiting, and then reading it back in.
#echo off
if "%~1" equ "_GO_" goto :main
cmd /c ^""%~f0" _GO_ %*^"
for /f "eol== delims=" %%A in (env.tmp) do set %%A
del env.tmp
exit /b
:main
call :label hello
set junk=saved
call :label stop
echo Never returns
exit /b
:label
echo %1
if "%1"=="stop" goto :saveEnvAndExit
exit /b
:saveEnvAndExit
set >env.tmp
exit
But variables with newline character (0x0A) in the value will not be preserved properly.
If you use exit /b X to exit from the function then it will set ERRORLEVEL to the value of X. You can then use the || conditional processing symbol to execute a command if ERRORLEVEL is non zero.
#echo off
setlocal
call :myfunction PASS || goto :eof
call :myfunction FAIL || goto :eof
echo Execution never gets here
goto :eof
:myfunction
if "%1"=="FAIL" (
echo myfunction: got a FAIL. Will exit.
exit /b 1
)
echo myfunction: Everything is good.
exit /b 0
Output from this script is:
myfunction: Everything is good.
myfunction: got a FAIL. Will exit.
Here's my solution that will support nested routines if all are checked for errorlevel
I add the test for errolevel at all my calls (internal or external)
#echo off
call :error message&if errorlevel 1 exit /b %errorlevel%<
#echo continuing
exit /b 0
:error
#echo in %0
#echo message: %1
set yes=
set /p yes=[no]^|yes to continue
if /i "%yes%" == "yes" exit /b 0
exit /b 1
Related
I'm trying to understand where in the code exactly does GOTO :EOF return to?
Here is the code:
SET count=1
FOR /f "tokens=*" %%G IN (somefile.txt) DO (call :subroutine "%%G")
GOTO :EOF
:subroutine
echo %count%:%1
set /a count+=1
GOTO :EOF
:EOF is a predefined label as Microsoft explains in documentation for command GOTO. The help output by running in a command prompt window goto /? explains also this special label for End Of File. But this predefined label is supported only with command extensions being enabled as by default.
The help output by running in a command prompt window call /? and of course also the documentation for command CALL explain both that goto :EOF should be used to exit a subroutine called with call :Label.
A subroutine is nothing else than another batch file embedded within current batch file called with command call. If the subroutine is at end of the batch file, real end of file marks the end of the subroutine.
But there can be multiple subroutines in a batch file.
So a command is needed for command interpreter to exit the subroutine on reaching a specific line in command processing and go back to the calling command line. goto :EOF as well as exit /B can be both used everywhere to either exit a subroutine or exit the current batch file processing.
In batch code in question the first goto :EOF is needed to exit batch file processing without an unwanted fall through to the subroutine code after finishing the loop.
The second goto :EOF in batch code of questioner is for exiting the subroutine and continue processing in FOR loop in second line. It does not exit processing of the batch file, it exits only the processing of the subroutine.
Note 1: goto EOF without a colon requires that there is really a line starting with :EOF in the batch file, i.e. the label EOF must exist in the file. goto :EOF always results in exiting subroutine/batch processing with command extensions enabled even if there is a label EOF in the batch file because of a line starting with :EOF.
Note 2: Command EXIT without parameter /B results always in exiting entire command process independent on calling hierarchy and independent on how the Windows command processor was started – with parameter /K to keep cmd.exe running as used when opening a command prompt window or with /C to close after command processing finished as used on double clicking a batch file. Therefore exit without /B should be used wisely in a batch file (best: never).
Note 3: exit /B without or with an exit code works always, but outputs an error message with command extensions disabled as demonstrated by this code:
#echo off
setlocal DisableExtensions
echo Use command exit /B with command extensions disabled.
exit /B 5
echo This line is not processed anymore.
Executing this batch file from within a command prompt window results in output of the error message:
The system cannot find the batch label specified - EOF
But the processing of the batch file is exited nevertheless with the exit code value 5 as it can be seen on running next in same command prompt window echo ERRORLEVEL is: %ERRORLEVEL% which outputs: ERRORLEVEL is: 5
It looks like there is assigned first the specified exit code value 5 to the dynamic variable ERRORLEVEL on using exit /B 5 and next is executed goto :EOF because of option /B. That fails because of disabled command extensions resulting in the error message and in exiting the batch file processing as it always occurs on a label to go to does not exist in a batch file.
In other words exit /B without or with an additional exit code always works, but there should be appended 2>nul to suppress the error message on command extensions disabled, i.e. use exit /B 2>nul (without exit code) or exit /B 5 2>nul (with exit code)
Note 4: ERRORLEVEL is not affected by goto :EOF, but the Microsoft GOTO documentation is mute on this topic. exit /B # sets ERRORLEVEL to # as documented by Microsoft. exit /B # can be also used instead of goto :EOF to exit a subroutine with a specific exit code evaluated on the command line calling the subroutine like on using the operators && or || or on next command after calling command line with if errorlevel X. However, explicitly exiting a batch file or a subroutine with a specific exit code is usually not needed as neither goto :EOF nor exit /B modify the current value of ERRORLEVEL.
Note 5: Do not use goto:EOF or call:Label in a batch file with no space between command GOTO respectively CALL (argument 0) and the label (argument 1). There should be always used goto :EOF and call :Label with a space as argument strings separator between command and label. The reason is that goto:EOF results in the attempts to find in current directory first a file with name goto: and next a file with name goto:EOF. The incorrect command call:Label results in searching for a file with name call: and next with name call:Label. The file system returns for both syntactically wrong commands twice to cmd.exe that the name is invalid. Then cmd.exe detects the colon as reason for the invalid name and splits the command up into command and label argument and finally runs the command with success. The usage of goto :EOF and call :Label does not cause any wrong file system accesses as cmd.exe immediately recognizes the string goto respectively call as internal command.
For details on ERRORLEVEL behavior see:
What are the ERRORLEVEL values set by internal cmd.exe commands?
Which cmd.exe internal commands clear the ERRORLEVEL to 0 upon success?
Single line with multiple commands using Windows batch file
GOTO :EOF is functionally equivalent to exit /B, but both forms only works when Extensions are enabled. The test for this point is very simple:
setlocal DisableExtensions
goto :EOF
Compare previous code vs. this one:
setlocal DisableExtensions
exit /B
This means that GOTO :EOF returns to the same point where exit /B would return.
:eof means "End of file". It's used to make the script finish without executing any of the commands below.
As the GOTO and CALL are using the same functionality to find a label you have an option to access the :EOF with CALL too:
CALL ::EOF
Same as GOTO (when CALL with the additional semicolon) the actual end-of-file will be the preferable point where the flow of the script will go. If you have your own label\function defined with EOF you can access it with single semicolon.
Though calling the :EOF has no much use - you can't put a code after the end of file so this line is actually doing nothing (though this will hit the performance as the end of file is parsed). And as GOTO and EXIT /B this wont work without enabled extensions.
If a script which should get exited in subroutines without closing the terminal when calling EXIT 1. There for I use this if which calls the script again.
This worked fine until I now discovered some issue with a quoted vertical bar as a parameter "!". I get an error stating that the command is misspelled.
Here is the part of the script that fails:
#ECHO OFF
SETLOCAL DISABLEDELAYEDEXPANSION
IF "%selfWrapped%"=="" (
REM this is necessary so that we can use "exit" to terminate the batch file,
REM and all subroutines, but not the original cmd.exe
SET selfWrapped=true
%ComSpec% /s /c ""%~0" %*"
GOTO :EOF
)
echo %*
ENDLOCAL
EXIT /B 0
Call:
test.cmd "hello world" "|"
Expected Output:
"hello world" "|"
I checked the the value of %* inside the IF but for it seems totally legitimate to use a vertical bar as well as any other quoted string.
So...
Why does the script fails?
How can I fix it?
I do not agree with some of the description in the link.
See exit /? accurate help description.
exit exits the interpreter.
exit 1 exits the interpreter with exitcode 1.
exit /b has similar behavior as goto :eof which exits
the script or called label. Errorlevel is not reset so allows
errorlevel from the previous command to be accessable after
exit of the script or the called label.
exit /b 1 exits the script or the called label with errorlevel 1.
If you oddly use exit /b at a CMD prompt, it is going to exit the interpreter.
Main code:
#ECHO OFF
SETLOCAL DISABLEDELAYEDEXPANSION
SET args=%*
SET "self=%~f0"
IF "%selfWrapped%"=="" (
#REM this is necessary so that we can use "exit" to terminate the batch file,
#REM and all subroutines, but not the original cmd.exe
SET "selfWrapped=true"
SETLOCAL ENABLEDELAYEDEXPANSION
ECHO !ComSpec! /s /c ""!self!" !args!"
"!ComSpec!" /s /c ""!self!" !args!"
GOTO :EOF
)
ECHO(%*
EXIT /B 0
Both use of GOTO :EOF and EXIT /B 0 will exit the script.
ENDLOCAL is implied at exit of the script.
Explicit use of ENDLOCAL is for when you want to end the
current local scope and continue the script. As always, being
explicit all the time is a choice.
Setting %* to args keeps the double quoting paired.
Quoting i.e. set "args=%*" can cause issue sometimes
though not using quotes allow code injection i.e.
arguments "arg1" ^& del *.*. If the del *.* is not going
to execute at the set line, then it will probably happen
at the ComSpec line. For this example, I chose not quote.
So, it is a choice.
You are using disabled expansion at start of the script. That
saves the ! arguments which is good. Before you execute
ComSpec though, enable delayed expansion and use !args!
which is now protected from the interpreter now not seeing |
or any other special character which may throw an error.
Your script fails as the | argument is exposed.
C:\Windows\system32\cmd.exe /s /c ""test.cmd" " | ""
The above is echoed evaluation of the ComSpec line with
setting #ECHO ON. Notice the pairing of quotes
i.e. "", " " and "". Notice the extra spacing inserted
around the | character as the interpreter does not consider
it as part of a quoted string.
Compared to updated code changes of echoed evaluation...:
"!ComSpec!" /s /c ""!self!" !args!"
The string between the quotes remain intact. No extra spacing
inserted into the string. The echoed evalution looks good and
executes good.
Disclaimer:
Expressing the workings of CMD is like walking a tight rope.
Just when you think you know, fall off the rope you go.
I don't see the necessity to append the parameter to your %ComSpec% /s /c ""%~0" %*" at all.
As you already use a variable (selfWrapped) to detect, if the wrapper call is necessary, you could also put your arguments into a variable.
set args=%*
Then you can simply use !args! in your child instance.
#ECHO OFF
setlocal DisableDelayedExpansion
IF "%selfWrapped%"=="" (
#REM this is necessary so that we can use "exit" to terminate the batch file,
#REM and all subroutines, but not the original cmd.exe
SET "selfWrapped=true"
SET ^"args=%*"
"%ComSpec%" /s /c ""%~f0""
GOTO :EOF
)
:Main
setlocal EnableDelayedExpansion
ECHO(!args!
EXIT /B 0
Now the only problem left, is the set args=%*.
If you can't control the content, then there is no way to access %* in a simple safe way.
Think of this batch invokations
myBatch.bat "abc|"
myBatch.bat abc^|
myBatch.bat abc^|--"|"
But you could use How to receive even the strangest command line parameters?
or Get arguments without temporary file
Btw. You could spare your child process, you can also exit from a function
Look at Exit batch script from inside a function
One correction to above answers.
Yes, ENDLOCAL is implied at the end of the script, but there's a catch.
I've found that with nested scripts, if you don't ENDLOCAL before you EXIT /B 1 you will not get your return code of 1 at the next level out script.
If you only ever EXIT /B 0, then this will not matter as the default return code is 0.
I'm trying to understand where in the code exactly does GOTO :EOF return to?
Here is the code:
SET count=1
FOR /f "tokens=*" %%G IN (somefile.txt) DO (call :subroutine "%%G")
GOTO :EOF
:subroutine
echo %count%:%1
set /a count+=1
GOTO :EOF
:EOF is a predefined label as Microsoft explains in documentation for command GOTO. The help output by running in a command prompt window goto /? explains also this special label for End Of File. But this predefined label is supported only with command extensions being enabled as by default.
The help output by running in a command prompt window call /? and of course also the documentation for command CALL explain both that goto :EOF should be used to exit a subroutine called with call :Label.
A subroutine is nothing else than another batch file embedded within current batch file called with command call. If the subroutine is at end of the batch file, real end of file marks the end of the subroutine.
But there can be multiple subroutines in a batch file.
So a command is needed for command interpreter to exit the subroutine on reaching a specific line in command processing and go back to the calling command line. goto :EOF as well as exit /B can be both used everywhere to either exit a subroutine or exit the current batch file processing.
In batch code in question the first goto :EOF is needed to exit batch file processing without an unwanted fall through to the subroutine code after finishing the loop.
The second goto :EOF in batch code of questioner is for exiting the subroutine and continue processing in FOR loop in second line. It does not exit processing of the batch file, it exits only the processing of the subroutine.
Note 1: goto EOF without a colon requires that there is really a line starting with :EOF in the batch file, i.e. the label EOF must exist in the file. goto :EOF always results in exiting subroutine/batch processing with command extensions enabled even if there is a label EOF in the batch file because of a line starting with :EOF.
Note 2: Command EXIT without parameter /B results always in exiting entire command process independent on calling hierarchy and independent on how the Windows command processor was started – with parameter /K to keep cmd.exe running as used when opening a command prompt window or with /C to close after command processing finished as used on double clicking a batch file. Therefore exit without /B should be used wisely in a batch file (best: never).
Note 3: exit /B without or with an exit code works always, but outputs an error message with command extensions disabled as demonstrated by this code:
#echo off
setlocal DisableExtensions
echo Use command exit /B with command extensions disabled.
exit /B 5
echo This line is not processed anymore.
Executing this batch file from within a command prompt window results in output of the error message:
The system cannot find the batch label specified - EOF
But the processing of the batch file is exited nevertheless with the exit code value 5 as it can be seen on running next in same command prompt window echo ERRORLEVEL is: %ERRORLEVEL% which outputs: ERRORLEVEL is: 5
It looks like there is assigned first the specified exit code value 5 to the dynamic variable ERRORLEVEL on using exit /B 5 and next is executed goto :EOF because of option /B. That fails because of disabled command extensions resulting in the error message and in exiting the batch file processing as it always occurs on a label to go to does not exist in a batch file.
In other words exit /B without or with an additional exit code always works, but there should be appended 2>nul to suppress the error message on command extensions disabled, i.e. use exit /B 2>nul (without exit code) or exit /B 5 2>nul (with exit code)
Note 4: ERRORLEVEL is not affected by goto :EOF, but the Microsoft GOTO documentation is mute on this topic. exit /B # sets ERRORLEVEL to # as documented by Microsoft. exit /B # can be also used instead of goto :EOF to exit a subroutine with a specific exit code evaluated on the command line calling the subroutine like on using the operators && or || or on next command after calling command line with if errorlevel X. However, explicitly exiting a batch file or a subroutine with a specific exit code is usually not needed as neither goto :EOF nor exit /B modify the current value of ERRORLEVEL.
Note 5: Do not use goto:EOF or call:Label in a batch file with no space between command GOTO respectively CALL (argument 0) and the label (argument 1). There should be always used goto :EOF and call :Label with a space as argument strings separator between command and label. The reason is that goto:EOF results in the attempts to find in current directory first a file with name goto: and next a file with name goto:EOF. The incorrect command call:Label results in searching for a file with name call: and next with name call:Label. The file system returns for both syntactically wrong commands twice to cmd.exe that the name is invalid. Then cmd.exe detects the colon as reason for the invalid name and splits the command up into command and label argument and finally runs the command with success. The usage of goto :EOF and call :Label does not cause any wrong file system accesses as cmd.exe immediately recognizes the string goto respectively call as internal command.
For details on ERRORLEVEL behavior see:
What are the ERRORLEVEL values set by internal cmd.exe commands?
Which cmd.exe internal commands clear the ERRORLEVEL to 0 upon success?
Single line with multiple commands using Windows batch file
GOTO :EOF is functionally equivalent to exit /B, but both forms only works when Extensions are enabled. The test for this point is very simple:
setlocal DisableExtensions
goto :EOF
Compare previous code vs. this one:
setlocal DisableExtensions
exit /B
This means that GOTO :EOF returns to the same point where exit /B would return.
:eof means "End of file". It's used to make the script finish without executing any of the commands below.
As the GOTO and CALL are using the same functionality to find a label you have an option to access the :EOF with CALL too:
CALL ::EOF
Same as GOTO (when CALL with the additional semicolon) the actual end-of-file will be the preferable point where the flow of the script will go. If you have your own label\function defined with EOF you can access it with single semicolon.
Though calling the :EOF has no much use - you can't put a code after the end of file so this line is actually doing nothing (though this will hit the performance as the end of file is parsed). And as GOTO and EXIT /B this wont work without enabled extensions.
I'm writing a complex batch patch file with generation of other files. I know that batch is not the best for it but I've mostly got it all working. However, there is a headache of keeping all subroutines duplicated in all files if I don't want to make a separate file for each subroutine. My question was whether there is any way of keeping a library file of multiple subroutines and call them somehow?
So I'm going to answer my own question because I managed to get something working.
Lets say you have main.bat and lib.bat files.
Main.bat
#ECHO off
SETLOCAL
SET return=
SET reference=this is just a reference variable
CALL lib.bat return "subroutine" "static arg" reference
IF NOT "%ERRORLEVEL%"=="0" (
ECHO Execution failed - %ERRORLEVEL%
EXIT /b 1
)
ECHO.
ECHO subroutine return value: "%return%"
ECHO.
CALL lib.bat NUL "procedure" "static arg" reference
ECHO.
CALL lib.bat return "error" "static arg" reference
IF NOT "%ERRORLEVEL%"=="0" (
ECHO Execution failed - %ERRORLEVEL%
EXIT /b 1
)
ENDLOCAL
EXIT /b 0
Lib.bat
#ECHO off
::
:: ===================================================================================
:: Library Main Handler
:: ===================================================================================
:: %~1 - [out] - NUL | reference to a return variable
:: %~2 - [in] - subroutine label to be invoked
:: %~3+ - [in] - optional arguments to the subroutine
::
:: ERRORLEVEL is passed through to the caller
::
SETLOCAL ENABLEDELAYEDEXPANSION ENABLEEXTENSIONS
SET callSub=%~2
SET return=
SET args=
IF "%callSub%"=="" (
ECHO Subroutine label was not provided to the library. 1>&2
EXIT /b 1
)
:buildUpArgumentList
IF "%~3"=="" GOTO end_buildUpArgumentList
SET args=%args% "%~3"
SHIFT /3
GOTO buildUpArgumentList
:end_buildUpArgumentList
IF NOT "%~1"=="NUL" (
call:%callSub% return %args%
IF NOT "!ERRORLEVEL!"=="0" (
EXIT /b !ERRORLEVEL!
)
) ELSE (
call:%callSub% %args%
IF NOT "!ERRORLEVEL!"=="0" (
EXIT /b !ERRORLEVEL!
)
)
(
ENDLOCAL
IF NOT "%~1"=="NUL" (
SET %~1=%return%
)
)
EXIT /b 0
::
:: ===================================================================================
:: Library Subroutine Definitions
:: ===================================================================================
::
:subroutine <r_return> <static> <r_reference>
SETLOCAL
ECHO subroutine^<static^>: "%~2"
ECHO subroutine^<r_reference^>: "!%~3!"
(
ENDLOCAL
SET %~1=subroutine executed OK
)
EXIT /b 0
:procedure <static> <r_reference>
SETLOCAL
ECHO procedure^<static^>: "%~1"
ECHO procedure^<r_reference^>: "!%~2!"
ENDLOCAL
EXIT /b 0
:error <r_return> <static> <r_reference>
SETLOCAL
ECHO error^<static^>: "%~2"
EXIT /b 2
ECHO error^<r_reference^>: "!%~3!"
(
ENDLOCAL
SET %~1=error executed OK
)
EXIT /b 0
Output:
subroutine<static>: "static arg"
subroutine<r_reference>: "this is just a reference variable"
subroutine return value: "subroutine executed OK"
procedure<static>: "static arg"
procedure<r_reference>: "this is just a reference variable"
error<static>: "static arg"
Execution failed - 2
Some comments:
The library subroutine invocation is similar to a regular function signature: () but without parentheses.
You will notice that the library code checks for NUL being passed. If that is the case, return value is neither passed to the subroutine nor is it returned back.
The subroutine arguments support n-number of arguments.
The library supports error level pass-through.
If a provided subroutine label does not exist within the library, batch will return ERRORLEVEL=1 and a message "The system cannot find the batch label specified - [label]."
Additional thoughts:
I am relatively new to batch scripting so not everything is perfect.
This was done in ~1hr and I'm sure its missing some stuff!
Should some escaping be performed when constructing the arguments array (i.e., quotes)?
Any other comments are much appreciated!
A simpler approach is to use the following trick:
Enclose the code that call the library functions between parentheses.
At beginning of the parentheses rename the current Batch file to other name, and rename the library file as the current Batch file.
Now you can call any library function in the same way as before.
Before parentheses ends, rename the files back to original names.
For example:
(
rem Switch the active context to the library file:
ren "%~0" main.bat
ren libraryFile.bat "%~0"
rem From this line on you may call any function in the library file, for example:
call :FUNCTION
rem Switch the context back to original file
ren "%~0" libraryFile.bat
ren main.bat "%~0"
)
For further details, see:
How to package all my functions in a batch file as a seperate file?
I want to know if it is possible to start a batch thin in a particular goto function from another batch?
thus not just starting another batch file but also have the "mother" batch select a particular goto option with in the "child"batch?
1.bat
call 2.bat /c goto :this
call 2.bat /c call :that
.
2.bat
if "%1"=="/c" shift & shift & %2 %3
goto :eof
:this
echo This!
goto :eof
:that
echo That!
goto :eof
EDIT: My original post was closest to correct. But I've corrected my mistake(s).
I double shift to remove %1 and %2 to the left, bringing any other variables passed to the %1 and %2 positions. I then execute %2 and %3 because the effect of the shifts won't take effect until the line is finished being executed / interpreted.
Just have the parent/mother batch file and pass a parameter to the child batch file.
mom.bat
#ECHO OFF
ECHO Here we go
CALL child.bat 3
PAUSE
child.bat
#ECHO OFF
IF "%1"=="1" Goto 1
IF "%1"=="2" Goto 2
IF "%1"=="3" Goto 3
EXIT
:1
ECHO 1!
PAUSE
EXIT
:2
ECHO 2!
PAUSE
EXIT
:3
ECHO 3!
PAUSE
EXIT
This example should echo 3! as the mother batch file passes the parameter 3 to the child batch file.
Yes, but it's a hack.
Normally you would do this with a bit of help from the called batch file.
main.bat
call second.bat :theFunction
*second.bat
goto %1
...
:theFunction
The hack uses a feature-bug, you only need the same label as in the second.bat.
And it only works if you start the second.bat without call
main.bat
call :theFunction
echo back in main
exit /b
:theFunction
second.bat
echo back in the func in main, this line will never reached
exit /b This line will also never reached
When the second.bat returns , it will return to the line after the call in main.bat
In the batch file that you are calling put this at the top
if not %1=="" goto :%1
In the batch file you are using to call it put
call b.bat labelname
Obviously this is limited depending on what you are trying to do but the basic functionality works.