Salut,
REMARQUE: tous les exmples sont testés dans un XPSP2
ERRORLEVEL est une variable interne elle indique l'état d'exécution de la dernière opération. Cette variable Contient le code de sortie du dernier programme Windows exécuté.
Elle fait partie des quelques variables dynamiques "non-caché" généré par le shell:
>> set /? | findstr /b "%"
1 2 3 4 5 6 7 8
|
%CD% - se développe en la chaîne du répertoire en cours.
%DATE% - se développe en la date actuelle en utilisant le même
%TIME% - se développe en l'heure en cours en utilisant le même
%RANDOM% - se développe en un nombre aléatoire compris entre 0 et 32767.
%ERRORLEVEL% - se développe en la valeur en cours de ERRORLEVEL
%CMDEXTVERSION% - se développe en le numéro de version des
%CMDCMDLINE% - se développe en la ligne de commande originale |
1) reinitialiser l'ERRORLEVEL "GLOBAL":
une des difference majeur entre un fichier d'extension .cmd et d'extension .bat et que le dernier ne reinitialise toujours pas l'ERRORLEVEL s'il rencontre l'une des commandes internes suivantes: PATH - APPEND - PROMPT - SET - ASSOC:
on va prendre un petit exemple, on va essayer d'essayer le premier choix vide puis on va mettre une chaine dans le deuxieme choix:
Dans le cas d'un '.bat' si on laisse notre choix vide l'errorlevel sera à "1" et même si dans notre deuxieme saisi on tape une chaine, l'errorlevel restera toujours à "1":
>> type c:\scripts\init.bat
1 2 3 4 5 6 7
|
@echo off
Set /p a=
echo %errorlevel%
Set /p b=
echo %errorlevel%
pause |
1 2 3 4 5
| >> c:\scripts\init.bat
1
hello
1 |
pour contourner se problème on peux utiliser differentes techniques l'une d'elles est de forcer l'ERRORLEVEL à se reinitialiser "GLOBALEMENT":
1 2 3 4 5 6 7 8 9
| >> type c:\scripts\init2.bat
@echo off
Set /p a=
echo %errorlevel%
cd.>nul
Set /p b=
echo %errorlevel%
pause |
1 2 3 4 5
| >> c:\scripts\init2.bat
1
hello
0 |
c'est dans ce cas qu'intervient l'extension '.cmd' pour corriger ce petit bug:
1 2 3 4 5 6 7 8 9
|
>> type c:\scripts\init.cmd
@echo off
Set /p a=
echo %errorlevel%
Set /p b=
echo %errorlevel%
pause |
1 2 3 4 5
| >> c:\scripts\init.cmd
1
hello
0 |
2) reinitialiser l'ERRORLEVEL de maniere Non-globale:
l'extension '.cmd' n'a pas resolu entierement le problème de la l'auto-reinitialisation de l'ERRORLEVEL.
1 2 3 4 5 6 7 8 9 10 11 12
| >> type c:\scripts\initbloc.bat
@echo off
:: && ^
(
echo NO ERROR
BREAK
REM.) || (
echo ERROR
)
pause |
le REM. va remettre l'errorlevel 0 (dans le bloc) essayez de l'enlever pour voir la différence.
3) errorlevel après une redirection:
après une redirection l'errorlevel ne se reinitialise pas:
1 2 3 4 5 6 7 8 9 10 11 12
|
>> type c:\scripts\initredir.bat
@echo off
commandnotfound 2>Nul
echo %errorlevel%
type nul > 3:\fichier.txt
echo %errorlevel%
pause |
1 2 3 4 5
| >> c:\scripts\initredir.bat
9009
Le chemin d'accès spécifié est introuvable.
9009 |
pour palier à ce problème on peux utiliser l'opérateurs "||"
1 2 3 4 5 6 7 8 9 10 11
|
>> type c:\scripts\initredir2.bat
@echo off
commandnotfound 2>Nul
echo %errorlevel%
type nul > 3:\fichier.txt || echo KO
echo %errorlevel%
pause |
1 2 3 4 5 6
| >> c:\scripts\initredir2.bat
9009
Le chemin d'accès spécifié est introuvable.
KO
1 |
4) retardé l'expansion de l'errorlevel:
lorsqu'on execute une boucle Forindo une autre instance CMD s'execute dans le contexte de la ligne de commande, ceci peux causer quelques problèmes, l'une d'elles est que la variable ERRORLEVEL n'est plus visibles dans la portée parente (contexte du batch):
1 2 3 4 5 6 7
| >> type c:\scripts\delayederror.bat
@echo off
for /f "delims=" %%a in ('"(commandnotfound & echo %ERRORLEVEL%) 2>Nul"') do Set ERROR=%%a
echo %ERROR%
pause |
1 2
| >> c:\scripts\delayederror.bat
0 |
pour que capturer l'errorlevel de la commande executer dans la boucle forindo on peux soit:
* utiliser un fichier temporaire:
1 2 3 4 5 6 7 8 9 10 11 12 13
| >> type c:\scripts\delayederror2.bat
@echo off
(
commandnotfound
call echo %%ERRORLEVEL%%
) > error.tmp 2>nul
for %%i in (type del) do (
for /f "delims=" %%a in ('%%i error.tmp') do SET ERROR=%%a
)
echo %ERROR%
pause |
1 2
| >> c:\scripts\delayederror2.bat
9009 |
ou bien capturé notre errorlevel puis retardé sa reinitialisation:
1 2 3 4 5 6 7 8 9
| >> type c:\scripts\delayederror3.bat
@echo off
for /f %%a in ('%Comspec% /v /c "commandnotfound&echo ^!errorlevel^!" 2^>Nul') do (
SET ERROR=%%a
)
echo %ERROR%
pause |
1 2
| >> c:\scripts\delayederror3.bat
9009 |
on utilise des carets "^" autour de la variable Errorlevel comme une astuce pour afficher le contenu de la variable dans le contexte de la boucle forindo, en fait, l'execution de la boucle se fait en une seul fois comme est le cas pour tout bloc de code, et ceci ne permetera pas à la variable d'afficher son vrai contenu, donc on initialise notre instance cmd explicitement en activant l'expansion retardé de variables "%COMSPEC% /V" puis on echappe nos "!" par des carets "^!" pour "s'echapper" du contexte de la boucle (execution en une seul fois) et laisser, ainsi, le temps à notre ERRORLEVEL de s'executer.
5) utilisation de l'operateur "||":
cet operateur est utiliser conjointement avec l'operateur "&&", il doit etre toujours après l'operateur "&&" sinon toute l'expression sera evalué
1 2 3 4
|
>> type c:\scripts\op.bat
2>Nul commandnotfound ||echo KO && echo OK |
1 2 3
| >> c:\scripts\op.bat
KO
OK |
1 2 3
| >> type c:\scripts\op2.bat
2>Nul commandnotfound && echo OK || echo KO |
1 2
| >> c:\scripts\op2.bat
KO |
cet operateur est concus pour traiter les erreurs d'une maniere simple, si la commande retourne une errolevel 1 ou + l'expression à droite de l'expression sera executé et l'ERRORLEVEL sera reinitialiser à 0, c'est super vous dite, mais que faire si une commande peux retourné plusieurs ERRORLEVEL comme c'est le cas pour XCOPY par exemple ?
1 2 3 4 5
| >> type c:\scripts\op3.bat
@echo off
2>Nul >Nul xcopy 8:\ 9:\ || echo ERREUR %ERRORLEVEL%
ECHO %ERRORLEVEL% |
1 2 3
| >> c:\scripts\op3.bat
ERREUR 0
4 |
comme vous pouvez le voir l'operateur "||" ne permet pas une gestion complexe de l'ERRORLEVEL.
Partager