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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
39
40
41
42
43
44
45
46
47
48
49
50
51
 C:\RepTest> test.cmd

--------------------------- ECHO.
file:_=@ 
file:_=@ 
file:_=@ 
file:_=@ 
file:_=@ 
--------------------------- ECHO+
file:_=@ 
file:_=@ 
file:_=@ 
file:_=@ 
file:_=@ 
--------------------------- ECHO=
fichier@1.txt 
fichier@2.txt 
fichier@3.txt 
fichier@4.txt 
fichier@5.txt 
--------------------------- ECHO,
fichier@1.txt 
fichier@2.txt 
fichier@3.txt 
fichier@4.txt 
fichier@5.txt 
--------------------------- ECHO;
fichier@1.txt 
fichier@2.txt 
fichier@3.txt 
fichier@4.txt 
fichier@5.txt 
--------------------------- ECHO[
file:_=@ 
file:_=@ 
file:_=@ 
file:_=@ 
file:_=@ 
--------------------------- ECHO]
file:_=@ 
file:_=@ 
file:_=@ 
file:_=@ 
file:_=@ 
--------------------------- ECHO(
fichier@1.txt 
fichier@2.txt 
fichier@3.txt 
fichier@4.txt 
fichier@5.txt 


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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
IF %ERRORLEVEL%==N (%ERRORLEVEL% est égale à N)
au contraire de la variable spéciale "ERRORLEVEL"

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
IF ERRORLEVEL==N (ERRORLEVEL=N ou ERRORLEVEL>N)
testez cet exemple:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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