2012-07-05 39 views
0

有兩個文件output.txt和test.bat。在output.txt的,只有一個線, '1 2 3 4' 和test.bat的含量是'for'語句在Windows批處理(.bat)文件中的'if'語句中打包時很奇怪

@echo off 
set condition=1 

if "%condition%" == "1" (
    for /F "tokens=1,2,3,4* delims= " %%a in (output.txt) do set variable=%%a 
    echo %variable% 
) 
pause 

運行test.bat的將回聲什麼。但是如果我稍微改變它,可以看到:

@echo off 
set condition=1 
for /F "tokens=1,2,3,4* delims= " %%a in (output.txt) do set variable=%%a 
echo %variable% 
if "%condition%" == "1" (
    for /F "tokens=1,2,3,4* delims= " %%a in (output.txt) do set variable=%%a 
    echo %variable% 
) 
pause 

它會回顯「1」兩次。 奇怪?錯誤?

回答

4

我不認爲這兩個腳本中的任何一個都會執行您認爲它的操作(具體而言,第二個腳本的工作原理只是因爲您在第一個腳本之後運行它)。

爲什麼它的行爲如此?

需要注意的重要一點是,除非延遲變量擴展打開,否則將在該命令執行前爲每個命令評估變量。這在使用IF時尤其關鍵,因爲parens內的整個命令塊被視爲一個命令

舉例說明:

SET foo= 
ECHO foo = %foo% 
IF 1==1 (
    SET foo=bar 
    ECHO foo = %foo% 
) 

以上腳本的輸出:

foo = 
foo = 

的原因是條件相當於

IF 1==1 SET foo=bar && ECHO foo = %foo% 

這只是一個命令,所以變量在它運行之前只擴展一次(特別是在之後它們不會擴展和之前的ECHO)。

這也是在你的腳本中發生的事情。由於%variable%設置爲在塊內回顯,所以ECHO實際上在塊輸入之前的值爲%variable%,因此您看不到「當前」值。

如何解決?

解決延遲變量擴展問題

有兩種方法可以解決這個問題。直截了當一個是使延遲變量擴展與SETLOCAL,然後參考變量的語法的!var!代替%var%

SETLOCAL ENABLEDELAYEDEXPANSION 
SET foo= 
ECHO foo = !foo! 
IF 1==1 (
    SET foo=bar 
    ECHO foo = !foo! 
) 

以上腳本將輸出:

foo = 
foo = bar 

通過破壞解決問題命令塊

還有另一種方法:記住變量在每個命令(或塊)執行之前擴展一次。因此,如果您想要在SETECHO之間進行擴展,您可以通過分解該塊來解決這個問題。

SET foo= 
ECHO foo = %foo% 
IF NOT 1==1 GOTO :proceed 
SET foo=bar 
ECHO foo = %foo% 
:proceed 

以上腳本也將輸出:

foo = 
foo = bar 

應用可以通過逆轉與NOT測試和使用GOTO可以跳過前面是「成功的」分支中的代碼做到這一點解決你的例子

這兩種方法轉化爲可以在本:

SETLOCAL ENABLEDELAYEDEXPANSION 
IF "%condition%" == "1" (
    FOR /F "tokens=1,2,3,4* delims= " %%a in (output.txt) DO SET variable=%%a 
    ECHO !variable! 
) 

或者這個:

IF NOT "%condition%" == "1" GOTO :proceed 
FOR /F "tokens=1,2,3,4* delims= " %%a in (output.txt) DO SET variable=%%a 
ECHO %variable% 
:proceed