2009-05-18 5 views
14

Почему следующий файл Windows Batch File Foo за ним следует Bar, а не Baz?Пакетный файл не может установить переменную среды в условном выражении

@echo off 
setlocal 

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

Выход на моей системе (Microsoft Windows XP [Версия 5.1.2600]) является:

Foo 
Bar 

Если удалить условный оператор, ожидаемый выход Foo и Baz наблюдается.

+0

Дубликат http://stackoverflow.com/questions/305605/weird-scope-issue-in-bat-file –

ответ

28

Что происходит, так это то, что замена переменных выполняется при чтении строки. То, что вы не в состоянии принять во внимание тот факт, что:

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

является один «линия», несмотря на то, что вы можете думать. Расширение "%_%" сделано доset заявление.

Что вам нужно, это отсроченное расширение. Почти каждый из моих командных скриптов начинается с "setlocal enableextensions enabledelayedexpansion", чтобы использовать полную мощность cmd.exe.

Так что моя версия скрипта будет:

@echo off 
setlocal enableextensions enabledelayedexpansion 

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

endlocal 

Это создает правильный "Foo", "Baz", а не "Foo", "Bar".

+2

Удивительно, спасибо за подробное объяснение. Я думаю, что я снова вернусь к этому точному ограничению, но в более ограниченной среде: http://stackoverflow.com/questions/879023/honoring-exit-codes-from-batch-files-invoked-by- msbuild К сожалению, у меня нет возможности включать расширения команд, если я использую задачу MSBuild 'Exec' ... hmmm ... –

3

попробовать это

@echo off 
setlocal 

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

Ответ на это так же, как ответ на: Weird scope issue in batch file. См. Там для более подробной информации. В основном переменное расширение выполняется во время чтения строки, а не во время выполнения.

Смежные вопросы