🏠 Home
⏎ Back

⏹ SETLOCAL

Syntaxe

SETLOCAL

SETLOCAL {EnableDelayedExpansion | DisableDelayedExpansion} {EnableExtensions | DisableExtensions}

Cles :

SETLOCAL généralement placé au début d'un fichier batch, commence la localisation des variables.

En publiant une commande SETLOCAL, un nouvel environnement local est créé en copiant toutes les variables de l’environnement parent. Toutes les modifications faites après cette commande restent confinées à ce contexte.

La délivrance d'une commande ENDLOCAL restaurera toutes les variables d'environnement à l'état qu'elles avaient avant l'émission du SETLOCAL.

En d'autres termes, ENDLOCAL rétablit l’environnement précédent, annulant les changements réalisés entre les deux.

💡

Un script est limité à 32 instanciations d'environnements. Si le script en appelle un autre par CALL, le script appelé dispose également de 32 niveaux et ainsi de suite.

Exemple 1

@ECHO OFF

SETLOCAL
ECHO SETLOCAL 1 : un environnement local est créé.
::Valeur initiale
SET STR=X01
ECHO "SET STR=X01  => %STR%"

::DEUXIEME VALEUR
SETLOCAL
ECHO SETLOCAL 2 : Un deuxième environnement est créé.
SET STR=X02
ECHO "SET STR=X02  => %STR%"

::RETOUR A LA VALEUR INITIALE
ENDLOCAL
ECHO APRES ENDLOCAL, le 2eme environnement est détruit.
ECHO La variable est restaurée à l'état précédent.
ECHO "STR = %STR%"

PAUSE

SETLOCAL 1 : un environnement local est créé.
"SET STR=X01  => X01"
SETLOCAL 2 : Un deuxième environnement est créé.
"SET STR=X02  => X02"
APRES ENDLOCAL, le 2eme environnement est détruit.
La variable est restaurée à l'état précédent.
"STR = X01"
Appuyez sur une touche pour continuer...
En image

Exemple 2

Ce script utilise toutes les instances possibles. Il créé une nouvelle instance

pour la variable N puis il dépile les environnements jusqu'au dernier.

::PILE
SETLOCAL
SET /A N=0
:START
SET /A "N=N+1"
ECHO "ENVIRONEMENT %N% N vaut %N%"
SETLOCAL
IF %N% LSS 32 GOTO START

::DEPILE
SET /A M=0
:START2
ENDLOCAL
SET /A "M=M+1"
IF DEFINED N ECHO "APRES ENLOCAL N vaut %N%"
IF %M% LSS 32 GOTO START2
PAUSE

"ENVIRONEMENT 1 N vaut 1"
"ENVIRONEMENT 2 N vaut 2"
"ENVIRONEMENT 3 N vaut 3"
"ENVIRONEMENT 4 N vaut 4"
"ENVIRONEMENT 5 N vaut 5"
"ENVIRONEMENT 6 N vaut 6"
"ENVIRONEMENT 7 N vaut 7"
"ENVIRONEMENT 8 N vaut 8"
"ENVIRONEMENT 9 N vaut 9"
"ENVIRONEMENT 10 N vaut 10"
"ENVIRONEMENT 11 N vaut 11"
"ENVIRONEMENT 12 N vaut 12"
"ENVIRONEMENT 13 N vaut 13"
"ENVIRONEMENT 14 N vaut 14"
"ENVIRONEMENT 15 N vaut 15"
"ENVIRONEMENT 16 N vaut 16"
"ENVIRONEMENT 17 N vaut 17"
"ENVIRONEMENT 18 N vaut 18"
"ENVIRONEMENT 19 N vaut 19"
"ENVIRONEMENT 20 N vaut 20"
"ENVIRONEMENT 21 N vaut 21"
"ENVIRONEMENT 22 N vaut 22"
"ENVIRONEMENT 23 N vaut 23"
"ENVIRONEMENT 24 N vaut 24"
"ENVIRONEMENT 25 N vaut 25"
"ENVIRONEMENT 26 N vaut 26"
"ENVIRONEMENT 27 N vaut 27"
"ENVIRONEMENT 28 N vaut 28"
"ENVIRONEMENT 29 N vaut 29"
"ENVIRONEMENT 30 N vaut 30"
"ENVIRONEMENT 31 N vaut 31"
"ENVIRONEMENT 32 N vaut 32"
Niveau maximal de récursivité de setlocal a été atteint.
"APRES ENLOCAL N vaut 31"
"APRES ENLOCAL N vaut 30"
"APRES ENLOCAL N vaut 29"
"APRES ENLOCAL N vaut 28"
"APRES ENLOCAL N vaut 27"
"APRES ENLOCAL N vaut 26"
"APRES ENLOCAL N vaut 25"
"APRES ENLOCAL N vaut 24"
"APRES ENLOCAL N vaut 23"
"APRES ENLOCAL N vaut 22"
"APRES ENLOCAL N vaut 21"
"APRES ENLOCAL N vaut 20"
"APRES ENLOCAL N vaut 19"
"APRES ENLOCAL N vaut 18"
"APRES ENLOCAL N vaut 17"
"APRES ENLOCAL N vaut 16"
"APRES ENLOCAL N vaut 15"
"APRES ENLOCAL N vaut 14"
"APRES ENLOCAL N vaut 13"
"APRES ENLOCAL N vaut 12"
"APRES ENLOCAL N vaut 11"
"APRES ENLOCAL N vaut 10"
"APRES ENLOCAL N vaut 9"
"APRES ENLOCAL N vaut 8"
"APRES ENLOCAL N vaut 7"
"APRES ENLOCAL N vaut 6"
"APRES ENLOCAL N vaut 5"
"APRES ENLOCAL N vaut 4"
"APRES ENLOCAL N vaut 3"
"APRES ENLOCAL N vaut 2"
"APRES ENLOCAL N vaut 1"
Appuyez sur une touche pour continuer...

En image
╔═════════════════════════════════════════╗
║      PILE D’ENVIRONNEMENTS CMD.EXE      ║
╠═════════════════════════════════════════╣
║ Niveau 32 │ N = 32  ← dernier SETLOCAL  ║
║ Niveau 31 │ N = 31                      ║
║ Niveau 30 │ N = 30                      ║
║ ...                                     ║
║ Niveau 03 │ N = 3                       ║
║ Niveau 02 │ N = 2                       ║
║ Niveau 01 │ N = 1  ← premier SETLOCAL   ║
╚═════════════════════════════════════════╝

╔═════════════════════════════════════════╗
║           DÉPILAGE PROGRESSIF           ║
╠═════════════════════════════════════════╣
║ ↓ ENDLOCAL                              ║
║ [N=32] supprimé                         ║
║ [N=31] actif                            ║
╟═════════════════════════════════════════╢
║ ↓ ENDLOCAL                              ║
║ [N=31] supprimé                         ║
║ [N=30] actif                            ║
╢═════════════════════════════════════════║
║ ...                                     ║
╢═════════════════════════════════════════║
║ ↓ ENDLOCAL                              ║
║ [N=1] supprimé                          ║
║ [GLOBAL] actif → N n’existe plus 🫣     ║
╚═════════════════════════════════════════╝

SETLOCAL {EnableDelayedExpansion | DisableDelayedExpansion}

💡 Expansion retardée (To be or not to be ?)

Dans cet exemple, nous allons introduire une notion clef relative à l'expansion retardée des variables.

Quand l’interpréteur cmd.exe lit un script batch, il analyse d’abord chaque bloc entre parenthèses en une seule fois avant de l’exécuter.

Pendant cette analyse, il remplace toutes les variables écrites avec %var% par leur valeur immédiate, c’est-à-dire celle qu’elles ont au moment de la lecture du bloc, pas pendant son exécution.

La variable est évaluée à la fin de l'exécution du bloc.

Ainsi, si une variable change à l’intérieur du bloc, cette nouvelle valeur n’est pas vue, car le remplacement a déjà eu lieu.

L'activation de l'expansion retardée modifie ce comportement : les variables entourées par ! (ex : !Result!) ne sont plus remplacées à la lecture du bloc, mais au moment de l’exécution réelle de chaque ligne.

Ce qui permet de voir les changements de valeur au fur et à mesure.

En exemple :

🞜 AVEC EXPANSION RETARDEE

::EXEMPLE COMMANDE FOR LOOP
SETLOCAL  ENABLEDELAYEDEXPANSION
FOR /L %%f in (1,1,5) DO (
    FOR /L %%g in (1,1,5) DO (
        SET /A Result = "%%f*%%g"
        ECHO %%f x %%g = !Result!
    )
)
PAUSE
En image

🞜 SANS EXPANSION RETARDEE

La variable est évaluée à la fin de l'exécution du bloc. Elle vaut 25 dans notre

exemple.

::EXEMPLE COMMANDE FOR LOOP
FOR /L %%f in (1,1,5) DO (
    FOR /L %%g in (1,1,5) DO (
        SET /A Result ="%%f*%%g"
        ECHO %%f x %%g = %Result%
    )
)
ECHO %Result%
PAUSE
En image