Como posso sair de um arquivo em lotes de dentro de uma sub-rotina?
Se eu usar o comando EXIT, simplesmente retornarei à linha em que chamei a sub-rotina e a execução continuará.
Aqui está um exemplo:
@echo off
ECHO Quitting...
CALL :QUIT
ECHO Still here!
GOTO END
:QUIT
EXIT /B 1
:END
EXIT /B 0
Resultado:
Quitting...
Still here!
Atualizar:
Esta não é uma resposta adequada, mas acabei fazendo algo como:
@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 canal duplo de:
CALL :SUBROUTINE_WITH_ERROR || GOTO HANDLE_FAIL
é uma abreviação de:
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, em vez de ter que fazer o LIGADOR lidar com a situação, mas isso pelo menos faz o trabalho.
Atualização # 2: Ao chamar uma sub-rotina de dentro de outra sub-rotina, chamada da maneira acima, chamo de dentro das sub-rotinas da seguinte maneira:
CALL :SUBROUTINE_WITH_ERROR || EXIT /B 1
Dessa forma, o erro se propaga de volta para o "principal", por assim dizer. A parte principal do lote pode lidar com o erro com o manipulador de erros GOTO: FAILURE
GOTO :EOF
%~0
à variável em vez detrue
:if not "%selfwrapped%"=="%~0" ( set selfwrapped=%~0 .... )
. Dessa forma, você pode usar o mesmo truque em vários scripts em lote que se chamam.%~0
) com todos os argumentos (%*
) de um cmd.exe aninhado, e/s
é usado para controlar a maneira como o%ComSpec%
argumento lida com aspas duplas ao redor do arquivo ligar.Que tal esse pequeno ajuste?
Resultado:
Tecnicamente, isso não sai da sub-rotina. Em vez disso, simplesmente verifica o resultado da sub-rotina e executa ações a partir daí.
fonte
Se você não quiser voltar do procedimento, não use
call
: usegoto
.fonte
Coloquei o tratamento de erros nos meus arquivos em lotes. Você pode chamar manipuladores de erro como este:
E aqui está o final do arquivo em lote:
fonte
Isso sairá do contexto atual e um contexto pai (ou seja, quando executado dentro de um
call
script de sub-rotina profunda, será encerrado):Ou, se você precisar do nível de erro 0:
Basicamente,
(goto) 2>nul
define o nível de erro como 1 (sem gerar um erro), retorna a execução ao contexto pai e o código após a execução de pipe duplo no contexto pai.type nul>nul
define o nível de erro como 0.UPD:
Para retornar a execução mais de duas vezes seguidas, encadeie vários
(goto) 2>nul ||
como este:Aqui está uma sub-rotina recursiva para retornar o contexto várias vezes:
Quando chamado de uma função recursiva:
a saída será:
fonte