Jak mogę wyjść z pliku wsadowego z podprogramu?
Jeśli użyję polecenia EXIT, po prostu wracam do wiersza, w którym wywołałem podprogram, i wykonywanie jest kontynuowane.
Oto przykład:
@echo off
ECHO Quitting...
CALL :QUIT
ECHO Still here!
GOTO END
:QUIT
EXIT /B 1
:END
EXIT /B 0
Wynik:
Quitting...
Still here!
Aktualizacja:
To nie jest właściwa odpowiedź, ale ostatecznie zrobiłem coś w stylu:
@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
Instrukcja dwururowa:
CALL :SUBROUTINE_WITH_ERROR || GOTO HANDLE_FAIL
jest skrótem od:
CALL :SUBROUTINE_WITH_ERROR
IF ERRORLEVEL 1 GOTO HANDLE_FAIL
Wciąż chciałbym wiedzieć, czy istnieje sposób na wyjście bezpośrednio z podprogramu, zamiast zmuszania CALLER do poradzenia sobie z sytuacją, ale to przynajmniej załatwia sprawę.
Aktualizacja nr 2: Podczas wywoływania podprogramu z innego podprogramu, wywoływanego w powyższy sposób, wywołuję w ten sposób z podprogramów:
CALL :SUBROUTINE_WITH_ERROR || EXIT /B 1
W ten sposób błąd rozprzestrzenia się z powrotem na „główny”, że tak powiem. Główna część partii może następnie obsłużyć błąd za pomocą procedury obsługi błędów GOTO: FAILURE
GOTO :EOF
%~0
do zmiennej zamiasttrue
:if not "%selfwrapped%"=="%~0" ( set selfwrapped=%~0 .... )
. W ten sposób możesz użyć tej samej sztuczki w wielu skryptach wsadowych, które się nawzajem wywołują.%~0
) ze wszystkimi argumentami (%*
) z zagnieżdżonego cmd.exe, i/s
służy do kontrolowania sposobu, w jaki%ComSpec%
argument obsługuje podwójne cudzysłowy wokół połączenie.A może ta drobna korekta?
Wynik:
Technicznie nie wychodzi to z podprogramu. Raczej po prostu sprawdza wynik podprogramu i podejmuje działania od tego momentu.
źródło
Jeśli nie chcesz wracać z procedury, nie używaj
call
: zamiast tego użyjgoto
.źródło
W moich plikach wsadowych umieściłem obsługę błędów. Możesz wywoływać programy obsługi błędów w następujący sposób:
A oto koniec pliku wsadowego:
źródło
Spowoduje to wyjście z bieżącego kontekstu i kontekstu nadrzędnego (tzn. Po wykonaniu w jednym
call
skrypcie głębokiego podprogramu nastąpi wyjście):Lub, jeśli potrzebujesz poziom błędu 0:
Zasadniczo
(goto) 2>nul
ustawia poziom błędu na 1 (bez wyświetlania błędu), zwraca wykonanie w kontekście nadrzędnym i kod po wykonaniu podwójnego potoku w kontekście nadrzędnym.type nul>nul
ustawia poziom błędu na 0.UPD:
Aby zwrócić wykonanie więcej niż dwa razy z rzędu, połącz kilka
(goto) 2>nul ||
takich:Oto podprogram rekurencyjny, który zwraca kontekst wielokrotnie zmienną:
Po wywołaniu z funkcji rekurencyjnej:
wyjście będzie:
źródło