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 .
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.
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 .
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
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.
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.
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.
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)
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
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
@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