Comment SETLOCAL et ENABLEDELAYEDEXPANSION fonctionnent-ils?
je remarque que dans la plupart des scripts, les deux sont généralement dans la même ligne que so:
SETLOCAL ENABLEDELAYEDEXPANSION
Sont les deux commandes distinctes et peuvent être écrites sur des lignes distinctes?
la mise ENABLEDELAYEDEXPANSION
avoir un effet défavorable sur un script si elle est définie sur les premières lignes du script et pas désactivé jusqu'à la fin du script?
4 réponses
ENABLEDELAYEDEXPANSION
est un paramètre passé à la commande SETLOCAL
(regardez setlocal /?
)
son effet dure toute la durée du script, ou un ENDLOCAL
:
lorsque la fin d'un script de lot est atteinte, un
ENDLOCAL
implicite est exécuté pour toute commandeSETLOCAL
émise par ce lot script.
En particulier, cela signifie que si vous utilisez SETLOCAL ENABLEDELAYEDEXPANSION
dans un script, tout changement de variable d'environnement sont perdus à la fin de celui-ci à moins que vous prendre des mesures spéciales .
je pense que vous devriez comprendre ce que l'expansion retardée signifie . Les réponses existantes ne l'expliquent pas (suffisamment) IMHO.
taper SET /?
explique assez bien la chose:
L'expansion variable de l'environnement différé est utile pour se déplacer les limites de l'expansion actuelle qui arrive quand une ligne de le texte est lu, pas lorsqu'il est exécuté. L'exemple suivant montre le problème avec l'expansion variable immédiate:
set VAR=before if "%VAR%" == "before" ( set VAR=after if "%VAR%" == "after" @echo If you see this, it worked )
n'afficherait jamais le message, puisque le %VAR % dans les deux énoncés IF est substitué lorsque la première instruction IF est lue, puisqu'il logiquement comprend le corps du Fi, qui est un énoncé composé. Donc la SI à l'intérieur de la déclaration composée est vraiment comparer "avant" avec "après" qui ne seront jamais égaux. De même, l'exemple suivant ne fonctionne pas comme prévu:
set LIST= for %i in (*) do set LIST=%LIST% %i echo %LIST%
en ce qu'il ne va PAS créer une liste de fichiers dans le répertoire courant, mais au lieu de cela va juste définir la variable LIST au dernier fichier trouvé. Encore une fois, c'est parce que le %liste% est élargi juste une fois lorsque le pour l'instruction est lue, et à ce moment la variable LIST est vide. De sorte que le
for %i in (*) do set LIST= %i
qui n'arrête pas de définir LIST au dernier fichier trouvé.
L'expansion de variable D'environnement retardée vous permet d'utiliser un différent caractère (le point d'exclamation) pour étendre les variables d'environnement à le temps d'exécution. Si l'extension de la variable delayed est activée, le des exemples pourraient être écrits comme suit pour fonctionner comme prévu:
set VAR=before if "%VAR%" == "before" ( set VAR=after if "!VAR!" == "after" @echo If you see this, it worked ) set LIST= for %i in (*) do set LIST=!LIST! %i echo %LIST%
un autre exemple est ce fichier de lot:
@echo off
setlocal enabledelayedexpansion
set b=z1
for %%a in (x1 y1) do (
set b=%%a
echo !b:1=2!
)
cela imprime x2
et y2
: chaque 1 est remplacé par un 2.
sans setlocal enabledelayedexpansion
, les points d'exclamation sont exactement cela, donc ils feront écho à !b:1=2!
deux fois.
parce que les variables d'environnement normales sont élargies quand une instruction (de bloc) est lire , l'expansion %b:1=2%
utilise la valeur b
a avant la boucle: z2
(mais y2
lorsqu'elle n'est pas définie).
la partie ENABLEDELAYEDEXPANSION est requise dans certains programmes qui utilisent l'expansion retardée, c'est-à-dire qui prennent la valeur des variables qui ont été modifiées à l'intérieur si ou pour les commandes en enfermant leurs noms dans des points d'exclamation.
si vous activez cette extension dans un script qui ne l'exige pas, le script se comporte différemment seulement s'il contient des noms enfermés dans des points d'exclamation !COMME! !CES!. Généralement, le nom est juste effacé, mais si une variable avec l' même nom existe pas par hasard, alors le résultat est imprévisible et dépend de la valeur de cette variable et l'endroit où il apparaît.
la partie SETLOCAL est nécessaire dans seulement quelques programmes spécialisés (récursifs), mais est couramment utilisé lorsque vous voulez être sûr de ne pas modifier une variable existante avec le même nom par hasard ou si vous voulez supprimer automatiquement toutes les variables utilisées dans votre programme. Cependant, comme il n'y a pas de commande séparée pour activer le l'expansion retardée, les programmes qui l'exigent doivent également inclure la partie locale de SETLOCAL.
un vrai problème existe souvent parce que toutes les variables définies à l'intérieur ne seront pas exportées lorsque le fichier de lot se termine. Il n'est donc pas possible d'exporter, ce qui nous a causé des problèmes. En conséquence, je viens de configurer le Registre pour qu'il utilise toujours l'extension retardée (Je ne sais pas pourquoi ce n'est pas la valeur par défaut, cela pourrait être un problème de compatibilité de vitesse ou d'héritage).)