19

Как я могу выйти из командного файла из подпрограммы?

Если я использую команду 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

4 ответа4

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 для выхода из текущей подпрограммы
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...

Технически это не выходит из подпрограммы. Скорее, он просто проверяет результат подпрограммы и предпринимает действия оттуда.

1

Если вы не хотите возвращаться из процедуры, не используйте call: вместо этого используйте goto .

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

:QUIT
EXIT /B 1

:END
EXIT /B 0
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)

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .