2009-05-18 19 views
14

¿Por qué la siguiente salida del archivo Windows Batch Foo seguido por Bar, en lugar de Baz?El archivo de proceso por lotes no puede establecer la variable de entorno dentro de la declaración condicional

@echo off 
setlocal 

set _=Foo 
echo %_% 
set _=Bar 
if 1==1 (
    set _=Baz 
    echo %_% 
) 

La salida en mi sistema (Microsoft Windows XP [Versión 5.1.2600]) es:

Foo 
Bar 

Si quito la sentencia condicional, el resultado esperado de Foo y Baz se observa.

+0

Duplicado de http://stackoverflow.com/questions/305605/weird-scope-issue-in-bat-file –

Respuesta

28

Lo que sucede es que la sustitución de variables se realiza cuando se lee una línea. Lo que estás no tener en cuenta es el hecho de que:

if 1==1 (
    set _=Baz 
    echo %_% 
) 

es uno "línea", a pesar de lo que puede pensar. La expansión de "%_%" se realiza antes de la instrucción set.

Lo que necesita es expansión retrasada. Casi todos y cada uno de mis scripts de comando comienzan con "setlocal enableextensions enabledelayedexpansion" para utilizar toda la potencia de cmd.exe.

Así que mi versión de la secuencia de comandos sería:

@echo off 
setlocal enableextensions enabledelayedexpansion 

set _=Foo 
echo !_! 
set _=Bar 
if 1==1 (
    set _=Baz 
    echo !_! 
) 

endlocal 

Esto genera la correcta "Foo", "Baz" en lugar de "Foo", "Bar".

+2

Impresionante, gracias por la explicación detallada. Creo que me estoy encontrando con esta limitación exacta una vez más, pero en un entorno más restringido aquí: http://stackoverflow.com/questions/879023/honoring-exit-codes-from-batch-files-invoked-by- msbuild Desafortunadamente no tengo la capacidad de activar las extensiones de comando si estoy usando la tarea 'Exec' de MSBuild ... hmmm ... –

3

probar esto

@echo off 
setlocal 

set _=Foo 
echo %_% 
set _=Bar 
if "1" NEQ "2" goto end 
set _=Baz 
echo %_% 
:end 
4

La respuesta a esto es la misma que la respuesta a: Weird scope issue in batch file. Vea allí para más detalles. La expansión básicamente variable se realiza en el tiempo de lectura de línea, no en el tiempo de ejecución.

Cuestiones relacionadas