Creo que debe entender qué retraso de expansión es. Las respuestas existentes no lo explican (suficientemente) en mi humilde opinión.
Typing SET /?
explica lo razonablemente bien:
entorno retardada expansión de variables es útil para moverse por las limitaciones de la actual expansión que se produce cuando se lee una línea de texto, no cuando se ejecuta . El siguiente ejemplo demuestra el problema inmediato la expansión de variables:
set VAR=before
if "%VAR%" == "before" (
set VAR=after
if "%VAR%" == "after" @echo If you see this, it worked
)
nunca mostrar el mensaje, ya que el% VAR% en ambos IF es sustituido cuando la primera instrucción IF se lee, ya que lógicamente incluye el cuerpo del IF, que es una declaración compuesta.Entonces, el IF dentro de la declaración compuesta realmente compara "antes" con "después", que nunca será igual. Del mismo modo, el ejemplo siguiente no funcionará como se esperaba:
set LIST=
for %i in (*) do set LIST=%LIST% %i
echo %LIST%
en que no va a construir una lista de archivos en el directorio actual, sino que simplemente va a establecer la variable de lista hasta el último archivo encontrado. De nuevo, esto se debe a que% LIST% se expande solo una vez cuando se lee la instrucción FOR , y en ese momento la variable LIST está vacía. Por lo que el bucle FOR real que estamos ejecutando es:
for %i in (*) do set LIST= %i
la que sólo mantiene la configuración lista hasta el último archivo encontrado.
La expansión de variable de entorno retrasada le permite utilizar un carácter diferente de (el signo de exclamación) para expandir las variables de entorno al tiempo de ejecución. Si se habilita la expansión de variables de retraso, los ejemplos anteriores podrían escribirse de la siguiente manera a funcionar como está previsto:
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%
Otro ejemplo es este archivo por lotes:
@echo off
setlocal enabledelayedexpansion
set b=z1
for %%a in (x1 y1) do (
set b=%%a
echo !b:1=2!
)
Esto imprime x2
y y2
: cada 1 es reemplazado por un 2.
Sin setlocal enabledelayedexpansion
, los signos de exclamación son solo eso, por lo que se hará eco de !b:1=2!
dos veces.
Debido a que las variables de entorno normales se expanden cuando un (bloque) declaración es leer, ampliando %b:1=2%
utiliza el valor b
tiene antes del bucle: z2
(pero y2
cuando no está establecido).
suelo poner esa línea en la parte superior de casi todos mis scripts y rara vez causa un problema, y me gusta cómo maneja mejor los caracteres de escape, especialmente al analizar XML o HTML. – djangofan
@djangofan ¿ha analizado el uso de AutoIt para tales tareas? Lo recomiendo Me alejé de batch/powershell/vbscript para AutoIt. – Mechaflash
Sí, he oído hablar de él. tal vez lo mire más de cerca. Aunque no me gusta pedir cosas de terceros ... y parece que también podría usar Powershell si ese es el caso. – djangofan