Как завершить пакетный файл Windows из «вызываемой» процедуры? - PullRequest
7 голосов
/ 01 июня 2009

У меня есть пакетный файл Windows, с несколькими подпрограммами, примерно такими:

call :a
goto :eof

:a
call :b
goto :eof

:b
:: How do I directly exit here from here?
goto :eof

Я запускаю это в окне cmd на Vista.
Если я обнаружу ошибку где-нибудь в командном файле, я хочу, чтобы он завершился с ненулевым уровнем ошибки. Есть ли что-нибудь, что я могу написать в подпрограмме: b, что приведет к прерыванию командного файла следующим образом.

  • Я попытался выйти, который закрывает все окно cmd. Это не то, что я хочу.
  • Я пробовал «выйти / B 1». Это возвращается к предыдущей рутине. Чтобы использовать эту схему после каждого «вызова», мне нужно было бы тщательно писать «errorlevel 1 exit / B 1» после каждого «вызова» для передачи ошибки обратно в стек вызовов. Я бы предпочел не писать эту строку после каждого звонка.

Эта статья была интересной, но ни одна из альтернатив не ведет себя так, как я хочу. http://www.computerhope.com/exithlp.htm

Есть ли другой способ?

Спасибо.

Ответы [ 2 ]

16 голосов
/ 01 июня 2009

Вы можете называть свои подпрограммы так:

call :b||exit /b 1

, что эквивалентно

call :b
if errorlevel 1 exit /b 1

Это немного короче и экономит одну строчку, но все равно не идеально, я согласен.

Кроме этого я не вижу пути.

РЕДАКТИРОВАТЬ: Хорошо, у меня есть способ, но это Pure Evil ™.

Неправильно используя максимальный размер стека и, следовательно, предел рекурсии, мы создаем другую подпрограмму, которая просто исчерпывает стек, рекурсивно вызывая себя:

@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 по существу остановил бы первый. Но почему-то это плохо сочетается с подпрограммами. Развертывание стека вызовов, похоже, все еще происходит.

0 голосов
/ 04 июня 2009

Вы можете создать файл exit.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

Exit.bat

@echo off
echo exit.bat
kill %1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...