Как завершить пакетный файл windows из подпрограммы "called"?
У меня есть пакетный файл windows, с несколькими подпрограммами в нем что-то вроде этого:
call :a
goto :eof
:a
call :b
goto :eof
:b
:: How do I directly exit here from here?
goto :eof
Я запускаю это в окне cmd на Vista.
Если я обнаруживаю ошибку где-то в пакетном файле, я хочу, чтобы она вышла с ненулевым уровнем ошибок. Есть ли что-нибудь, что я могу написать в подпрограмме :b, что заставит пакетный файл завершиться так.
- я попробовал "exit", который закрывает все окно cmd. Это не то, чего я хочу.
- Я попробовал "exit / B 1". Это возвращает нас к предыдущей процедуре. Чтобы использовать эту схему после каждого "вызова", мне нужно было бы тщательно написать "if errorlevel 1 exit /B 1 "после каждого "вызова", чтобы передать ошибку обратно в стек вызовов. Я бы предпочел не писать эту строчку после каждого звонка.
эта статья была интересной, но не альтернативы ведут себя так, как я хочу. http://www.computerhope.com/exithlp.htm
есть еще способ?
спасибо.
2 ответов
вы можете назвать свои подпрограммы так:
call :b||exit /b 1
что эквивалентно
call :b
if errorlevel 1 exit /b 1
это немного короче и экономит вам одну строку, но это все еще не идеально, я согласен.
кроме этого, я не вижу способа.
EDIT: хорошо, у меня есть способ, но это чистое зло™.
неправильно используя максимальный размер стека и, следовательно, предел рекурсии, мы создаем другую подпрограмму, которая просто исчерпывает стек рекурсивно называя себя:
@echo off
echo Calling a
call :a
echo Called a
goto :eof
:a
echo Calling b
call :b
echo Called b
goto :eof
:b
echo Trying to exit
call :exit
goto :eof
:exit
call :exit
это, однако, приведет к неприятному сообщению об ошибке
****** B A T C H R E C U R S I O N exceeds STACK limits ****** Recursion Count=704, Stack Usage=90 percent ****** B A T C H PROCESSING IS A B O R T E D ******
кроме того, это займет около 2 секунд на моей машине.
вы можете подавить сообщение об ошибке, изменив call
заявление следующим образом:
call :exit >nul 2>&1
который перенаправит все, что он хочет вывести в большую пустоту.
но учитывая время, необходимое для заполнения стека, я думаю, что первый вариант будет облегчающий.
Я также рассматривал использование второго пакетного файла, который при запуске без call
по существу остановит первый. Но почему-то это не очень хорошо играет с подпрограммами. Развертывание стека вызовов, по-видимому, все еще происходит.
вы можете создать выход.файл bat, который убивает верхний файл bat по имени заголовка.
пример:
A. bat
@echo off
title A.bat
echo A.bat
call B.bat
echo A.bat
B. bat
@echo off
echo B.bat
exit.bat A.bat
echo B.bat
выход.летучая мышь!--9-->
@echo off
echo exit.bat
kill %1