2014-04-27 5 views
4
@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 
)  

작동되지 | 작동 "| 당신의 입력이 인식되지 않는 에코"그러나 "는 고토 start1"는 스크립트를내 고토 리디렉션이 작동하지만 넣어 경우 에코

:explore_room 
@echo room explored 
goto start1 
pause 
:examine_door 
@echo door examined 
pause 
:examine_wall 
@echo wall examined 
pause 

답변

2

하는 방식의 충돌 @MC ND에 의해 Check if label exists cmd 및 @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 
+0

+1 논의하지만 이유 조건부 실행 에코 작업용 작동 되었는가? 'goto'는 전체적으로 괄호와 리디렉션/조건부 실행 컨텍스트를 깰 수 있지만 전체 응답이라고 생각하지는 않습니다 ... – npocmaka

3
@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 

예 :

학술적를 사용하여 여기 desribed 그렇게하기
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 
+0

하지만 조건부 실행 및 다른 명령이 작동 한 후 'goto'가 작동하지 않는 이유는 무엇입니까? – npocmaka

+0

'call'과'goto'가이 경우에 다르게 작동하기 때문에 (레이블이 존재하지 않을 때) :'call'은 errorlevel = 1을 리턴하고 execution_!을 계속합니다. 'goto' 실행 취소 ... – Aacini

+0

하지만 왜'goto' 만 취소 되었습니까? – npocmaka

2

이것은 정말 이상하고 interessting 버그입니다!

GOTO 대신 CALL을 사용하면 그 원인이 분명해질 것입니다.

goto :notExist || call :someLabel 

당신은 배치 파일의 외부 레이블을 호출하는

불법과 같은 오류 메시지가 나타납니다.

분명히 파서는 여기서 cmd- 라인 컨텍스트로 전환합니다!

첫 번째 고토가 레이블을 찾지 못한 경우이 작업이 수행됩니다.
처음 사용할 때 call 모두 정상적으로 작동합니다.

call :noLabel 2>nul || goto :thisWorks 

이것은 실패 goto의 일반적인 부작용 보인다.
goto가 실패하면 일반적으로 배치 파일을 즉시 중지합니다.

그러나 || 연산자를 사용하면 다음 명령이 강제로 실행됩니다.

하지만 더 효과가있는 것 같습니다. exit /b이므로이 효과를 사용하여 함수를 남길 수 있습니다.

@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 

interessting 출력

VAR = 333! VAR!

그래서 goto :noLabelexit /b 같은 역할을하고 또한 암시 ENDLOCAL|| set var=333!var! 부분 전에 실행 완료.

같은 문제는 (그러나 || 연산자없이)가 아니라 제와 오도 Dostips: Rules for label names vs GOTO and CALL