⏹ SETLOCAL
Syntaxe
SETLOCAL
SETLOCAL {EnableDelayedExpansion | DisableDelayedExpansion} {EnableExtensions | DisableExtensions}
Cles :
- EnableDelayedExpansion : Active l’expansion retardée des variables — c’est-à-dire que les variables sont développées au moment de l’exécution, plutôt qu’à la lecture de la ligne.
- DisableDelayedExpansion : Désactive l’expansion retardée — les variables sont alors développées au moment de l’analyse (parse), avant l’exécution.
- EnableExtensions : Tente d’activer les extensions de commandes (fonctionnalités supplémentaires de CMD, comme SET /A, IF EXIST, FOR /F, etc.).
- DisableExtensions : Tente de désactiver ces extensions de commandes.
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...
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...
╔═════════════════════════════════════════╗ ║ 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
🞜 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