Brève explication sur quelques notions basiques
salut,
le but de ce post est de donner quelques explications sur des notions basiques.
(j'espère que les explications seront claires)
.BAT VS .CMD
Quel est la différence entre un fichier de commande ayant l'extension .BAT et un autre ayant l'extension .CMD ?
L'une des différences est l'intérprétation de la variable ERRORLEVEL, dans le cas des fichiers .BAT la variable ERRORLEVEL est limité au erreurs retournées par des commandes, par contre dans le cas des fichiers .CMD cette variable n'est plus spécifique aux retours d'erreurs seulement, mais aussi, en cas de reussite.
Exemple
Code:
1 2 3 4 5 6 7 8 9 10 11 12
|
@Echo oFF
set test=CMD
Call :batVScmd 6
set test=BAT
If errorlevel 6 (echo BAT) else (echo CMD)
goto:eof
:batVScmd
exit /b %1
goto :eof |
essayez d'enregistrer ce code dans un fichier d'extension .bat puis dans un fichier .cmd pour voir la différence.
Code:
1 2 3 4 5 6
|
c:\RepTest> batfile.bat
BAT
c:\RepTest> cmdfile.cmd
CMD |
TOKENS VS DELIMS
Quelle est la différence entre TOKENS et DELIMS ?
Supposant qu'on a un fichier "tokVSdel.txt"
Code:
1 2 3
|
a b c d e f g
1 2 3 4 5 6 7 |
on veux maintenant, lire chaque ligne de ce fichier, pour ce faire on va utiliser une boucle FOR/F
Code:
1 2
|
For /F "?" %%a In (tokVSdel.txt) Do Echo %%a |
Que choisir alors [TOKENS=*] ou bien [DELIMS=] ?
Pour répondre à cette question il faut comprendre leurs fonctionnements : Voici un exemple qui montre les différences entre ces deux options
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13
|
@echo off
(set Str= Ceci est un test )
for /f "tokens=*" %%i in ("%Str%") do Set Token=%%~i
for /f "delims=" %%i in ("%Str%") do Set Delim=%%~i
for /f "tokens=*" %%i in ('echo\%Str%') do Set Echot=%%~i
for /f "delims=" %%i in ('echo\%Str%') do Set Echod=%%~i
echo Str_Origin=[%Str%]
echo Token-Echo=[%Token%]
echo Delim-Echo=[%Delim%]
echo Token+Echo=[%Echot%]
echo Delim+Echo=[%Echod%]
pause |
Code:
1 2 3 4 5 6 7 8
|
C:\RepTest> test.cmd
Str_Origin=[ Ceci est un test ]
Token-Echo=[Ceci est un test ]
Delim-Echo=[ Ceci est un test ]
Token+Echo=[Ceci est un test ]
Delim+Echo=[ Ceci est un test ] |
=> remarquez l'interprétation des espaces dans chaque boucle.
Echo. VS Echo[+(,=;+\/]
dans la documentation Echo suivi d'un point "ECHO." créer une ligne vide
Code:
1 2 3 4 5
|
ECHO Ligne1
ECHO Ligne2
ECHO.
ECHO Ligne4 |
mais aussi permet de ne rien afficher si la variable n'est pas définie
Code:
1 2 3 4
|
Set NON_DEFNIE=
ECHO %NON_DEFINIE%
ECHO.%NON_DEFINIE% |
Mais souvent on utilise d'autres caractères à la place de "." :
Code:
1 2 3 4 5 6 7 8 9
| ECHO,
ECHO;
ECHO+
ECHO=
ECHO(
ECHO/
ECHO\
ECHO[
ECHO] |
Quel est la différence entre la syntaxe de la documentation et ces variantes ?
Voici 2 cas qui montrent que le "." peut causer des problèmes:
1) Conflit entre les noms de fichiers en "ECHO" et la commande "ECHO."
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
@Echo oFF
CD.>ECHO
ECHO. ECHO.
ECHO, ECHO,
ECHO; ECHO;
ECHO+ ECHO+
ECHO= ECHO=
ECHO( ECHO(
ECHO/ ECHO/
ECHO\ ECHO\
ECHO[ ECHO[
ECHO] ECHO]
DEL ECHO
Pause |
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
C:\RepTest> test.cmd
'ECHO.' n'est pas reconnu en tant que commande interne
ou externe, un programme ex‚cutable ou un fichier de commandes.
ECHO,
ECHO;
ECHO+
ECHO=
ECHO(
ECHO/
ECHO\
ECHO[
ECHO] |
2) L'ERV (expansion retardée de variable) et les variables de substitutions:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
|
@Echo oFF
md __test
pushd __test
setlocal enabledelayedexpansion
for /l %%a in (1 1 5) Do cd.>fichier_%%a.txt
echo --------------------------- ECHO.
for %%a in (*.*) do Set "file=%%a" & echo.!file:_=@!
echo --------------------------- ECHO+
for %%a in (*.*) do Set "file=%%a" & echo+!file:_=@!
echo --------------------------- ECHO=
for %%a in (*.*) do Set "file=%%a" & echo=!file:_=@!
echo --------------------------- ECHO,
for %%a in (*.*) do Set "file=%%a" & echo,!file:_=@!
echo --------------------------- ECHO;
for %%a in (*.*) do Set "file=%%a" & echo;!file:_=@!
echo --------------------------- ECHO[
for %%a in (*.*) do Set "file=%%a" & echo[!file:_=@!
echo --------------------------- ECHO]
for %%a in (*.*) do Set "file=%%a" & echo]!file:_=@!
echo --------------------------- ECHO(
for %%a in (*.*) do Set "file=%%a" & echo(!file:_=@!
popd
rd /s /q __test
pause |
EnableExtensions VS DisableExtensions:
voici quelques différences entre le mode d'extension activé (par défaut) et le mode d'extension désactivé.
interprétation des variables dynamiques:
Si on désactive les extensions de commandes les variables dynamiques ne sont plus reconnues.
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
@Echo oFF
Set VAR=ERRORLEVEL RANDOM DATE CD CMDCMDLINE TIME CMDEXTVERSION
echo DISABLEEXTENSIONS
echo -----------------
for %%a in (%VAR%) do Cmd /e:off /Ccall echo %%a %%%%a%%%
echo.
echo ENABLEEXTENSIONS
echo -----------------
for %%a in (%VAR%) do Cmd /e:on /Ccall echo %%a %%%%a%%%
Pause |
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
C:\RepTest> test.cmd
DISABLEEXTENSIONS
-----------------
ERRORLEVEL %ERRORLEVEL%
RANDOM %RANDOM%
DATE %DATE%
CD %CD%
CMDCMDLINE %CMDCMDLINE%
TIME %TIME%
CMDEXTVERSION %CMDEXTVERSION%
ENABLEEXTENSIONS
-----------------
ERRORLEVEL 0
RANDOM 25664
DATE 14/02/2010
CD D:\Documents and Settings\Administrateur\Bureau
CMDCMDLINE Cmd /e:on /Ccall echo CMDCMDLINE Cmd /e:on /Ccall echo CMDCMDLINE %CMDCMDLINE%
TIME 17:05:56,56
CMDEXTVERSION 2 |
commandes non-reconnues:
Si les extensions de commandes sont désactivées la commande COLOR n'est plus reconnue.
** COLOR
Code:
1 2 3 4 5 6 7 8 9 10
|
@Echo oFF
:: setlocal enableextensions
setlocal disableextensions
color 0e
endlocal
Pause |
Comportement de quelques commandes:
Si on désactive les extensions de commandes, certaines auront un comportement différent:
A) La commande MD:
La création d'arborescence n'est plus reconnue.
Code:
1 2
|
Md racine\arbo1\arbo2\arbo3 |
cette commande par défaut (extensions activées) va créer une arborescence dans le répertoire en cours, si on désactive
l'extension des commandes elle retournera une erreur puisqu'elle essaiera de créer un répertoire "racine\arbo1\arbo2\arbo3" ce qui est impossible puisque le caractère "\" est un caractère réservé dans le nommage de fichiers/dossiers
B) La commande CALL:
si les extensions sont déactivées,la commande "CALL" ne permet plus d'appel à une étiquette :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
@Echo oFF
::Setlocal EnableExtensions
Setlocal DisableExtensions
set _test=false
call :eti
echo %_test%
pause
exit /b
:eti
set _test=true
exit /b |
C) La commande GOTO:
avec la désactivation des extensions, goto :EOF attend l'étiquette :EOF (End-Of-File)
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
@Echo oFF
::setlocal enableextensions
setlocal disableextensions
set eof=enableextensions
echo %eof%
goto :eof
:eof
set eof=disableextensions
echo %eof% |
D) La commande IF:
==> tiré du help de la commande "IF"
Si les extensions de commandes sont désactivées vous ne pouvez pas utiliser les syntaxes suivantes :
Code:
1 2 3 4 5 6
|
if [/i] Chaîne1 OpComparaison Chaîne2 Commande [else Expression]
if cmdextversion Nombre Commande [else Expression]
if defined Variable Commande [else Expression] |
E) La commande FOR:
si les extensions de commandes sont désactivées, pour la boucle FOR : Les formes d'itération (/L) , de récursivité (/R) et de formatage de fichiers (/F) ne sont plus reconnues :
Code:
1 2 3 4 5 6 7 8 9
|
Setlocal DisableExtensions
For /L %%a In (1 1 5) Do Echo %%a
For /R . %%a In (.) Do Echo %%a
For /F %%a In (Fichier) Do Echo %%a
Endlocal |
F) Il y a aussi d'autres commandes SHIFT DEL,etc.
FOR/F VS FOR/R
Dans une recherche récursive, Quelle est la différence entre ces deux syntaxes :
Code:
1 2 3 4 5
|
For /r . %%a in (*) Do echo;%%a
For /f "delims=" %%a in ('Dir/s/a-d/b') Do echo;%%a |
Mac LAK et Nono075 ont répondu à cette question dans ce post
ERRORLEVEL VS %ERRORLEVEL%
1- Fixer un ERRORLEVEL:
tous les codes d'erreurs retournés sont des nombres connus:
Code:
1 2
|
IF %ERRORLEVEL%==N (%ERRORLEVEL% est égale à N) |
au contraire de la variable spéciale "ERRORLEVEL"
Code:
1 2
|
IF ERRORLEVEL==N (ERRORLEVEL=N ou ERRORLEVEL>N) |
testez cet exemple:
Code:
1 2 3 4 5 6
|
echo ceci est un test | find "test">nul
if ERRORLEVEL==0 echo ERRORLEVEL
REM Si la commande précédente renvoie 0 ou plus grand "c'est toujours le cas !!"
if %ERRORLEVEL%==0 echo %%ERRORLEVEL%%
REM Si la commande précédente renvoie 0 |
puis ceci:
Code:
1 2 3 4 5 6
|
echo ceci est un test | find "##">nul
if ERRORLEVEL==0 echo ERRORLEVEL
REM Si la commande précédente renvoie 0 ou plus grand "c'est toujours le cas !!"
if %ERRORLEVEL%==0 echo %%ERRORLEVEL%%
REM Si la commande précédente renvoie 0 |
puis fixer un code retour avec la variable spéciale ERRORLEVEL, on doit tester le code d'erreur en deux partie.
Code:
1 2 3
| IF ERROELEVEL X IF NOT ERRORLEVEL Y (ACTION)
--------------- -------------------
Partie 1 partie 2 |
la première partie va tester si ERRORLEVEL est supérieur à "X" et la deuxième partie va tester si ERRORLEVEL est inférieur à "Y"
voici un exemple pour avoir un résultat exact avec ERRORLEVEL:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
::::::::::::::::::::::::::::::::::::::::::::::::::::::::
@Echo oFF
CALL :EXITCODE 1
If ERRORLEVEL 0 IF NOT ERRORLEVEL 1 ECHO ERRORLEVEL=0
If ERRORLEVEL 1 IF NOT ERRORLEVEL 2 ECHO ERRORLEVEL=1
IF ERRORLEVEL 2 IF NOT ERRORLEVEL 3 ECHO ERRORLEVEL=2
ECHO.
If ERRORLEVEL 0 ECHO ERRORLEVEL=0 OR ERRORLEVEL ^> 0
If ERRORLEVEL 1 ECHO ERRORLEVEL=1 OR ERRORLEVEL ^> 1
IF ERRORLEVEL 2 ECHO ERRORLEVEL=2 OR ERRORLEVEL ^> 2
Pause
GoTo:EOF
:EXITCODE
EXIT /B %1
GOTO:EOF
::::::::::::::::::::::::::::::::::::::::::::::::::::::::: |
2- Structures de blocs :
La variable ERRORLEVEL a l'avantage d'être utilisé dans une structure de bloc sans activer l'expansion retardé des variables, au contraire de la variable %ERRORLEVEL%
3- Désactivation des extensions:
quand les extensions sont désactivées on peut utiliser ERRORLEVEL à la place de %ERRORLEVEL%
Code:
1 2 3 4 5 6 7 8 9
|
@echo off
:: Setlocal enableextensions
setlocal disableextensions
IF "%ERRORLEVEL%"=="0" echo %%ERRORLEVEL%%
IF NOT ERRORLEVEL 1 echo ERRORLEVEL
pause |
@suivre