Jak zakończyć plik wsadowy po napotkaniu błędu?

Mam plik wsadowy, który w kółko wywołuje ten sam plik wykonywalny z różnymi parametrami. Jak sprawić, by proces zakończył się natychmiast, jeśli jedno z połączeń zwróci kod błędu dowolnego poziomu?

W zasadzie chcę odpowiednika MSBuild ' s ContinueOnError=false.

 232
Author: Nakilon, 2009-04-09

10 answers

Sprawdź errorlevel w instrukcji if, a następnie exit /b (Zamknij tylko plik atch b, a nie cały cmd.proces exe) dla wartości innych niż 0.

same-executable-over-and-over.exe /with different "parameters"
if %errorlevel% neq 0 exit /b %errorlevel%

Jeśli chcesz, aby wartość błędu propagowała się poza twoim plikiem wsadowym

if %errorlevel% neq 0 exit /b %errorlevel%
/ Align = "left" / Będziesz potrzebował czegoś więcej:
setlocal enabledelayedexpansion
for %%f in (C:\Windows\*) do (
    same-executable-over-and-over.exe /with different "parameters"
    if !errorlevel! neq 0 exit /b !errorlevel!
)

Edit: musisz sprawdzić błąd po każdym poleceniu. Nie ma globalnego typu" On error goto " w cmd.exe/command.com Zaktualizowałem również mój kod na CodeMonkey , chociaż nigdy nie spotkałem się z negatywnym poziomem błędu w żadnym z moich batch-hacking NA XP lub Vista.

 245
Author: system PAUSE,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 10:31:14

Dodaj || goto :label do każdej linii, a następnie zdefiniuj :label.

Na przykład utwórz to .plik cmd:

@echo off

echo Starting very complicated batch file...
ping -invalid-arg || goto :error
echo OH noes, this shouldn't have succeeded.
goto :EOF

:error
echo Failed with error #%errorlevel%.
exit /b %errorlevel%

Zobacz także pytanie o wyjście podprogramu plików wsadowych .

 214
Author: Fowl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-20 10:18:19

Najkrótszy:

command || exit /b

Jeśli potrzebujesz, możesz ustawić kod wyjścia:

command || exit /b 666

I możesz także logować:

command || echo ERROR && exit /b
 64
Author: Benoit Blanchon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-20 15:26:00

Jedna drobna aktualizacja, powinieneś zmienić sprawdzanie "if errorlevel 1" na następujące...

IF %ERRORLEVEL% NEQ 0 

Dzieje się tak dlatego, że NA XP można uzyskać liczby ujemne jako błędy. 0 = żadnych problemów, Wszystko inne jest problemem.

I miej na uwadze sposób, w jaki DOS obsługuje testy "if ERRORLEVEL". Zwróci true, jeśli liczba, którą sprawdzasz, to ta liczba lub wyższa, więc jeśli szukasz konkretnych numerów błędów, musisz zacząć od 255 i pracować w dół.

 24
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-27 14:34:05

Oto program polyglot dla bash i Windows CMD, który uruchamia serię poleceń i kończy działanie, jeśli któreś z nich się nie powiedzie:

#!/bin/bash 2> nul

:; set -o errexit
:; function goto() { return $?; }

command 1 || goto :error

command 2 || goto :error

command 3 || goto :error

:error

:; exit 0
exit /b 0

:error
exit /b %errorlevel%

Używałem tego typu rzeczy w przeszłości dla wielu platform ciągłej integracji skrypt.

 8
Author: Erik Aronesty,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-18 14:55:15

Preferuję formę polecenia OR, ponieważ uważam je za najbardziej czytelne (jako przeciwny do posiadania if po każdej komendzie). Jednak naiwny sposób robienie tego, command || exit /b %ERRORLEVEL% jest złe .

Dzieje się tak dlatego, że batch rozszerza zmienne podczas pierwszego odczytu wiersza, a raczej niż wtedy, gdy są używane. Oznacza to, że jeśli command w linii powyższe nie powiodło się, plik wsadowy kończy się poprawnie, ale kończy z kodem zwrotnym 0, ponieważ to właśnie wartość %ERRORLEVEL% była na początku Kolejka Oczywiście jest to niepożądane w naszym skrypcie, więc musimy włączyć opóźniona rozbudowa , Tak:

SETLOCAL EnableDelayedExpansion

command-1 || exit /b !ERRORLEVEL!
command-2 || exit /b !ERRORLEVEL!
command-3 || exit /b !ERRORLEVEL!
command-4 || exit /b !ERRORLEVEL!

Ten fragment wykona polecenia 1-4, a jeśli któreś z nich się nie powiedzie, zakończ z tym samym kodem zakończenia, co nieudane polecenie.

 3
Author: Xarn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-17 14:20:18

Nie zawsze możemy polegać na poziomie błędu, ponieważ wiele razy zewnętrzne programy lub skrypty wsadowe nie zwracają kodów zakończenia.

W takim przypadku możemy użyć ogólnych sprawdzeń błędów takich jak:

IF EXIST %outfile% (DEL /F %outfile%)
CALL some_script.bat -o %outfile%
IF NOT EXIST %outfile%  (ECHO ERROR & EXIT /b)

I jeśli program wysyła coś do konsoli, możemy to również sprawdzić.

some_program.exe 2>&1 | FIND "error message here" && (ECHO ERROR & EXIT /b)
some_program.exe 2>&1 | FIND "Done processing." || (ECHO ERROR & EXIT /b)
 2
Author: Amr Ali,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-26 06:11:44

Bez względu na to, jak próbowałem, poziom błędu zawsze pozostaje 0, nawet jeśli msbuild nie powiodło się. Więc zbudowałem swoje obejście:

Zbuduj projekt i Zapisz dziennik budowy.log

SET Build_Opt=/flp:summary;logfile=Build.log;append=true

msbuild "myproj.csproj" /t:rebuild /p:Configuration=release /fl %Build_Opt%

Wyszukaj ciąg "0 Error" w dzienniku budowy, Ustaw wynik na var

FOR /F "tokens=* USEBACKQ" %%F IN (`find /c /i "0 Error" Build.log`) DO (
    SET var=%%F
)
echo %var%

Pobranie ostatniego znaku, który wskazuje ile linii zawiera szukany ciąg

set result=%var:~-1%

echo "%result%"

If string not found, then error > 0, build failed

if "%result%"=="0" ( echo "build failed" )
To rozwiązanie zostało zainspirowane postem Mechaflasha na Jak ustawia wyjście poleceń jako zmienną w pliku wsadowym

I https://ss64.com/nt/syntax-substring.html

 1
Author: E.Seven,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-05 15:13:22

Po prostu użyj ERRORLEVEL, aby osiągnąć pożądany rezultat. Istnieją dwie zmienne w poleceniu ERRORLEVEL, które określałyby, czy proces się nie powiódł lub powiódł, zmiennymi tymi są ERRORLEVEL 0 i ERRORLEVEL 1 (1 dla fail, 0 dla pass). Oto przykład użycia tego pliku wsadowego:

echo off
cls
ping localhost 
errorlevel 0 goto :good
errorlevel 1 goto :bad

:good
cls
echo Good!
echo[
pause
exit

:bad
cls
echo Bad!
echo[
pause
exit

Oto link z Więcej informacji, jeśli potrzebujesz go: Errorlevels

 0
Author: PryroTech,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-25 02:43:16
@echo off

set startbuild=%TIME%

C:\WINDOWS\Microsoft.NET\Framework\v3.5\msbuild.exe c:\link.xml /flp1:logfile=c:\link\errors.log;errorsonly /flp2:logfile=c:\link\warnings.log;warningsonly || goto :error

copy c:\app_offline.htm "\\lawpccnweb01\d$\websites\OperationsLinkWeb\app_offline.htm"

del \\lawpccnweb01\d$\websites\OperationsLinkWeb\bin\ /Q

echo Start Copy: %TIME%

set copystart=%TIME%

xcopy C:\link\_PublishedWebsites\OperationsLink \\lawpccnweb01\d$\websites\OperationsLinkWeb\ /s /y /d

del \\lawpccnweb01\d$\websites\OperationsLinkWeb\app_offline.htm

echo Started Build: %startbuild%
echo Started Copy: %copystart%
echo Finished Copy: %TIME%

c:\link\warnings.log

:error

c:\link\errors.log
 -2
Author: Demican,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-05 23:50:41