Comment faire pour terminer un fichier batch en cas d'erreur?

j'ai un fichier batch qui appelle le même exécutable encore et encore avec des paramètres différents. Comment puis-je faire résilier immédiatement si l'un des appels renvoie un code d'erreur de n'importe quel niveau?

en gros, je veux l'équivalent du ContinueOnError=false de MSBuild .

232
demandé sur Nakilon 2009-04-09 18:56:16

10 réponses

cochez la case errorlevel dans la case if , puis exit /b (quitter le fichier b atch seulement, et non le cmd entier.exe process) pour des valeurs autres que 0.

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

si vous voulez que la valeur du niveau d'erreur se propage en dehors de votre fichier de lots

if %errorlevel% neq 0 exit /b %errorlevel%

mais si c'est à l'intérieur d'un for ça devient un peu délicat. Vous aurez besoin de quelque chose comme:

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: Vous avez pour vérifier l'erreur après chaque commande. Il n'y a pas de construction globale de type "On error goto" dans cmd.exe / command.lot com. J'ai aussi mis à jour mon code par CodeMonkey , bien que je n'ai jamais rencontré de niveau d'erreur négatif dans aucun de mes piratage de lots sur XP ou Vista.

245
répondu system PAUSE 2017-05-23 10:31:14

ajouter || goto :label à chaque ligne, puis définir un :label .

par exemple, créer ceci .fichier 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%

Voir aussi question concernant la sortie du sous-programme de fichiers par lots .

214
répondu Fowl 2017-03-20 10:18:19

le plus court:

command || exit /b

si vous avez besoin, vous pouvez définir le code de sortie:

command || exit /b 666

et vous pouvez aussi vous connecter:

command || echo ERROR && exit /b
64
répondu Benoit Blanchon 2014-02-20 15:26:00

une mise à jour mineure, vous devez changer les vérifications pour "if errorlevel 1" à ce qui suit...

IF %ERRORLEVEL% NEQ 0 

c'est parce que sur XP vous pouvez obtenir des nombres négatifs comme erreurs. 0 = aucun problème, tout le reste est un problème.

et gardez à l'esprit la façon dont le DOS gère les tests" IF ERRORLEVEL". Il retournera true si le nombre que vous vérifiez est ce nombre ou plus élevé donc si vous cherchez des numéros d'erreur spécifiques que vous devez commencer avec 255 et travailler vers le bas.

24
répondu 2014-10-27 14:34:05

voici un polyglot programme pour BASH et Windows CMD qui exécute une série de commandes et quitte si l'une d'elles échoue:

#!/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%

j'ai utilisé ce type de chose dans le passé pour une plate-forme multiple intégration continue script.

8
répondu Erik Aronesty 2017-10-18 14:55:15

je préfère la forme ou de commande, car je les trouve les plus lisibles (comme plutôt que d'avoir une si après chaque commande). Cependant, la manière naïve de ce faisant, command || exit /b %ERRORLEVEL% est erroné .

c'est parce que le lot étend les variables quand une ligne est lue pour la première fois, plutôt que lorsqu'ils sont utilisés. Cela signifie que si le command dans la ligne ci-dessus échoue, le fichier batch sort correctement, mais il sort avec le code de retour 0, parce que c'est ce la valeur de %ERRORLEVEL% était au début de la ligne. Évidemment, cela n'est pas souhaitable dans notre script, donc nous devons activer expansion retardée , comme suit:

SETLOCAL EnableDelayedExpansion

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

ce fragment exécutera les commandes 1-4, et si l'une d'elles échoue, il sortie avec le même code de sortie que la commande défaillante.

3
répondu Xarn 2018-08-17 14:20:18

nous ne pouvons pas toujours dépendre du niveau D'erreur, car souvent les programmes externes ou les scripts de traitement par lots ne retournent pas les codes de sortie.

dans ce cas, nous pouvons utiliser des contrôles génériques pour les échecs comme celui-ci:

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

et si le programme produit quelque chose à console, nous pouvons le vérifier aussi.

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
répondu Amr Ali 2014-11-26 06:11:44

peu importe comment j'ai essayé, le niveau d'erreur reste toujours 0 même lorsque msbuild a échoué. Donc j'ai construit mon contournement:

Projet de construction et d'enregistrer le journal de Construire.log

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

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

rechercher la chaîne de caractères" 0 erreur "dans le journal de construction, définir le résultat à var

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

obtenir le dernier caractère, qui indique combien de lignes contient la chaîne de recherche

set result=%var:~-1%

echo "%result%"

si la chaîne n'est pas trouvée, alors erreur > 0, build failed

if "%result%"=="0" ( echo "build failed" )

cette solution a été inspirée par le post de Mechaflash à comment définir la sortie des commandes comme une variable dans un fichier discontinu

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

1
répondu E.Seven 2017-09-05 15:13:22

il suffit d'utiliser ERRORLEVEL pour atteindre le résultat que vous souhaitez. Il y a deux variables dans la commande ERRORLEVEL qui détermineraient si un processus a échoué ou réussi, ces variables sont ERRORLEVEL 0 et ERRORLEVEL 1 (1 pour échec, 0 pour réussite). Voici un exemple d'utilisation dans un fichier Batch:

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

voici un lien avec plus d'info si vous en avez besoin: Errorlevels

0
répondu PryroTech 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
répondu Demican 2013-09-05 23:50:41