2009-05-18 184 views
14

爲什麼下面的Windows批處理文件輸出Foo followedby Bar,而不是Baz批處理文件未能條件語句中設置環境變量

@echo off 
setlocal 

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

我的系統上的輸出(微軟的Windows XP [版本5.1.2600)是:

Foo 
Bar 

如果我刪除了條件語句中,FooBaz預期輸出觀察。

+0

重複的http://stackoverflow.com/questions/305605/weird-scope-issue-in-bat-file – 2009-05-18 11:43:12

回答

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`任務...嗯... – 2009-05-18 18:06:03

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。請參閱此處瞭解更多詳情。基本上可變擴展是在線路讀取時完成的,而不是在執行時間。

相關問題