서브 루틴에서 배치 파일 종료


18

서브 루틴 안에서 배치 파일을 종료하려면 어떻게해야합니까?

EXIT 명령을 사용하면 서브 루틴을 호출 한 행으로 돌아가고 실행이 계속됩니다.

다음은 그 예입니다.

@echo off
ECHO Quitting...
CALL :QUIT
ECHO Still here!
GOTO END

:QUIT
EXIT /B 1

:END
EXIT /B 0

산출:

Quitting...
Still here!

최신 정보:

이것은 적절한 답이 아니지만 나는 다음과 같은 행을 따라 무엇인가를 끝내었다.

@echo off
CALL :SUBROUTINE_WITH_ERROR || GOTO HANDLE_FAIL
ECHO You shouldn't see this!
GOTO END

:SUBROUTINE_WITH_ERROR
ECHO Simulating failure...
EXIT /B 1

:HANDLE_FAIL
ECHO FAILURE!
EXIT /B 1

:END
ECHO NORMAL EXIT!
EXIT /B 0

이중 파이프 구문 :

CALL :SUBROUTINE_WITH_ERROR || GOTO HANDLE_FAIL

다음의 약식 :

CALL :SUBROUTINE_WITH_ERROR 
IF ERRORLEVEL 1 GOTO HANDLE_FAIL    

나는 여전히 CALLER가 상황을 처리하도록하지 않고 서브 루틴에서 직접 빠져 나갈 수있는 방법이 있는지 알고 싶지만 최소한이 일은 끝내야한다.


업데이트 # 2 : 위의 방식으로 호출 된 다른 서브 루틴 내에서 서브 루틴을 호출 할 때 나는 서브 루틴 내에서 다음과 같이 호출합니다.

CALL :SUBROUTINE_WITH_ERROR || EXIT /B 1

이렇게하면 오류는 말하자면 "주"로 다시 전파됩니다. 일괄 처리의 주요 부분은 오류 처리기로 오류를 처리 할 수 ​​있습니다. GOTO : FAILURE

답변:


21

이 파일을 배치 파일의 맨 위에 추가하십시오.

@ECHO OFF
SETLOCAL

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
)

그럼 당신은 간단하게 전화 할 수 있습니다 :

  • EXIT [errorLevel] 전체 파일을 종료하려면
  • EXIT /B [errorLevel] 현재 서브 루틴을 종료한다.
  • GOTO :EOF 현재 서브 루틴을 종료한다.

+1 실제로 언급 GOTO :EOF
afrazier

1
아주 좋아. 나는 작은 수정을했고, 할당했다. %~0 대신에 변수에 true: if not "%selfwrapped%"=="%~0" ( set selfwrapped=%~0 .... ). 그렇게하면 서로 호출하는 여러 배치 스크립트에서 동일한 트릭을 사용할 수 있습니다.
GolezTrol

이것은 훌륭한 해결책입니다. 그것이 어떻게 작동하는지 설명하는 편집 가치가 있다고 생각하십니까? 모든 것을 압축 해제하고 실제로 배치 파일을 호출한다는 것을 알게되었습니다. ( %~0 ) 모든 인수 ( %* ) 중첩 된 cmd.exe에서 /s 방법을 제어하는 ​​데 사용됩니다. %ComSpec% 인수는 호출 주위의 큰 따옴표를 처리합니다.
Sean

@Sean은 간결함이 대부분의 사람들에게 더 유용하다는 것을 안다. 필자가 작성한 이후 7 년 동안 더 많은 문서가 요청되지 않았으므로 수요가 많지 않은 것처럼 보입니다. 나는 또한 사람들이 스스로를 찾고 duping / fragmenting 문서에 어떤 가치가 있다고 생각합니다. 그러나 아마 몇 명 더 묻는다면 뭔가를 추가 할 수 있습니다. 또한 CW이기 때문에 편집을 제안 할 수도 있습니다.
Merlyn Morgan-Graham

3

이 작은 조정은 어때?

@echo off
ECHO Quitting...
CALL :QUIT
:: The QUIT subroutine might have set the error code so let's take a look.
IF ERRORLEVEL 1 GOTO :EOF
ECHO Still here!
GOTO END

:QUIT
EXIT /B 1

:END
EXIT /B 0

산출:

Quitting...

기술적으로 이것은 서브 루틴 내에서 빠져 나오지 않습니다. 오히려 단순히 서브 루틴의 결과를 확인하고 거기에서 조치를 취합니다.


2
고마워, 그건 분명히 일을 끝내고 내가 더 좋은 대답을 찾지 못하면 내가해야 할 일이 생길거야. 그러나, 길고 복잡한 배치 파일의 모든 호출 후에 해당 행을 붙여 넣을 필요는 없습니다.
Brown

1

절차에서 돌아오고 싶지 않은 경우에는 사용하지 마십시오. call대신에 goto.

@echo off
ECHO Quitting...
GOTO :QUIT
ECHO Will never be there!
GOTO END

:QUIT
EXIT /B 1

:END
EXIT /B 0

문제의 요점은 서브 루틴 (즉, 호출 사용)에서이를 수행하는 방법입니다. 그래서 응답하지 않습니다.
Steve Crane

1

배치 파일에 오류 처리를 넣습니다. 다음과 같은 오류 처리기를 호출 할 수 있습니다.

CALL :WARNING "This is" "an important" "warning."

다음은 배치 파일의 끝입니다.

::-------------------------------------------------------------------
::  Decisions
::-------------------------------------------------------------------
:INFO
IF "_DEBUG"=="true" (
  ECHO INFO: %~1
  IF NOT "%~2"=="" ECHO          %~2
  IF NOT "%~3"=="" ECHO          %~3
)
EXIT /B 0
:WARNING
ECHO WARNING: %~1
IF NOT "%~2"=="" ECHO          %~2
IF NOT "%~3"=="" ECHO          %~3
EXIT /B 0
:FAILURE
ECHO FAILURE: %~1
IF NOT "%~2"=="" ECHO          %~2
IF NOT "%~3"=="" ECHO          %~3
pause>nul
:END
ECHO Closing Server.bat script
FOR /l %%a in (5,-1,1) do (TITLE %TITLETEXT% -- closing in %%as&PING.exe -n 2 -w 1 127.0.0.1>nul)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.