Sai do arquivo batch da sub-rotina

18

Como posso sair de um arquivo de lote de dentro de uma sub-rotina?

Se eu usar o comando EXIT, simplesmente retornarei à linha onde chamei a sub-rotina e a execução continuará.

Veja um exemplo:

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

:QUIT
EXIT /B 1

:END
EXIT /B 0

Saída:

Quitting...
Still here!

Atualização:

Esta não é uma resposta adequada, mas acabei fazendo algo nos moldes de:

@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

A declaração de pipe duplo de:

CALL :SUBROUTINE_WITH_ERROR || GOTO HANDLE_FAIL

é uma abreviação para:

CALL :SUBROUTINE_WITH_ERROR 
IF ERRORLEVEL 1 GOTO HANDLE_FAIL    

Eu ainda adoraria saber se há uma maneira de sair diretamente de uma sub-rotina do que ter que fazer o CHAMADOR lidar com a situação, mas isso pelo menos faz o trabalho.

Atualização 2: Ao chamar uma sub-rotina de outra sub-rotina, chamada da maneira acima, eu chamo de dentro das sub-rotinas assim:

CALL :SUBROUTINE_WITH_ERROR || EXIT /B 1

Dessa forma, o erro se propaga de volta para o "main", por assim dizer. A parte principal do lote pode, então, manipular o erro com o manipulador de erros GOTO: FAILURE

    
por Brown 10.12.2009 / 15:09

4 respostas

21

Adicione isto ao topo do seu arquivo de lote:

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

Você pode simplesmente ligar:

  • EXIT [errorLevel] se você quiser sair do arquivo inteiro
  • EXIT /B [errorLevel] para sair da sub-rotina atual
  • GOTO :EOF para sair da sub-rotina atual
por 27.10.2010 / 19:20
3

Que tal este pequeno ajuste?

@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

Saída:

Quitting...

Tecnicamente, isso não sai de dentro da sub-rotina. Em vez disso, ele simplesmente verifica o resultado da sub-rotina e toma medidas a partir daí.

    
por 08.12.2009 / 18:56
1

Se você não quiser voltar do procedimento, não use call : em vez disso, use goto .

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

:QUIT
EXIT /B 1

:END
EXIT /B 0
    
por 27.03.2011 / 11:50
1

Eu coloquei o tratamento de erros nos meus arquivos em lote. Você pode chamar manipuladores de erro como este:

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

E aqui está o final do arquivo de lote:

::-------------------------------------------------------------------
::  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)
    
por 07.12.2011 / 22:01

Tags