@echo off
:start1
set /p input=action :
for /f "tokens=1-2 delims= " %%a in ("%input%") do (
goto :%%~a_%%~b >nul 2>&1 || goto start1
)
if I put "| | echo your input is not recognized" it works, but the "goto start1" crashes the script
:explore_room
@echo room explored
goto start1
pause
:examine_door
@echo door examined
pause
:examine_wall
@echo wall examined
pause
@echo off
:start1
set /p input=action :
call :%input: =_% 2>nul
if errorlevel 1 echo your input is not recognized
goto start1
:explore_room
@echo room explored
pause
exit /B 0
:examine_door
echo door examined
pause
exit /B 0
:examine_wall
echo wall examined
pause
exit /B 0
Example:
action : examine door
door examined
Presione una tecla para continuar . . .
action : explore hall
your input is not recognized
action : explore room
room explored
Presione una tecla para continuar . . .
¿Desea terminar el trabajo por lotes (S/N)? s
A way to do that using the technics desribed here : Check if label exists cmd by @MC ND and @dbenham :
@echo off
:start1
set /p input=action :
for /f "tokens=1-2 delims= " %%a in ("%input%") do (
findstr /ri /c:"^ *:%%~a_%%~b " /c:"^ *::%%~a_%%~b$" "%~f0" >nul 2>nul && goto :%%~a_%%~b)
goto:start1
:explore_room
@echo room explored
goto:start1
This is a really strange and interessting bug!
The cause will be obvious when I used CALL
instead of GOTO
.
goto :notExist || call :someLabel
You get an error message like
Illegal to call a label outside of a batch file.
Obviously the parser switches to a cmd-line context here!
This is done when the first goto fails to find the label.
When you use first a call
all works fine.
call :noLabel 2>nul || goto :thisWorks
This seems to be a general side effect of a failing goto
.
When a goto fails, it normally stops immediatly the batch file.
But with the ||
operator the next command will be forced to execute.
But it seems that it works more like an exit /b
, so you can use this effect to leave a function.
@echo off
setlocal DisableDelayedExpansion
set var=111
call :myFunc
set var
exit /b
:myFunc
setlocal EnableDelayedExpansion
set var=222
goto :noLabel 2>nul || set var=333!var!
echo This will be never reached
exit /b
The interessting output
var=333!var!
So the goto :noLabel
acts like an exit /b
and it also done the implicit ENDLOCAL
before the part || set var=333!var!
is executed.
The same issue (but without the ||
operator) was discussed at Dostips: Rules for label names vs GOTO and CALL
来源:https://stackoverflow.com/questions/23327304/my-goto-redirect-is-not-working-but-works-with-echo