報價在DOS批處理文件通常被誤用。與UNIX shell腳本不同,DOS批處理語言沒有經過深思熟慮。例如,當isit
變量包含引號
set isit="Y"
那麼上述if語句擴展到
IF ""Y"" == "Y" GOTO saidyes
IF ""Y"" == "N" GOTO saidno
因爲cmd.exe的計算表達式之前不會刪除"%isit%"=="Y"
引號。
isit
中的引用不應與在此處發佈的原始批處理文件發生。但是,您經常在批處理文件中處理路徑名,Windows將長文件名用引號引起來隱藏空白。例如,如「C:\ Program Files(x86)\ Microsoft Visual Studio 10.0 \ VC」。要解決這一點,通常的做法是寫if語句這樣:
IF ["%isit%"] == ["Y"] GOTO saidyes
IF [%isit%] == ["Y"] GOTO saidyes
IF [%isit%] == [Y] GOTO saidyes
對於set isit="Y"
變爲:
IF [""Y""] == ["Y"] GOTO saidyes
IF ["Y"] == ["Y"] GOTO saidyes
IF ["Y"] == [Y] GOTO saidyes
和set isit=Y
:
IF ["Y"] == ["Y"] GOTO saidyes
IF [Y] == ["Y"] GOTO saidyes
IF [Y] == [Y] GOTO saidyes
和set isit=
:
IF [""] == ["Y"] GOTO saidyes
IF [] == ["Y"] GOTO saidyes
IF [] == [Y] GOTO saidyes
這遠不夠優雅,但至少現在適用於帶引號和不帶引號的變量。它也適用於isit
爲空時。 Oftenly批處理文件停止,因爲空的變量:
set x=
REM ...
IF %x% == x GOTO x
因爲現在的if語句擴展爲:
IF == x GOTO x
和CMD.EXE失敗。這些錯誤通常很難調試。
詭計很古老;我記得在MSDOS中已經使用它。請注意,方括號不會被cmd.exe評估;他們只是一些很少使用的字符。但這只是一個竅門。任何先進的批處理腳本需要一個dequoting功能:
@echo off
setlocal EnableExtensions
setlocal EnableDelayedExpansion
REM ...
set /P isit="Y/N: "
call :dequote isit
REM ...
IF "!isit!" == "Y" GOTO saidyes
IF "!isit!" == "N" GOTO saidno
REM ...
goto done
:dequote
for /f "delims=" %%A in ('echo %%%1%%') do set %1=%%~A
goto :eof
:done
的deqote
-subroutine消除周圍傳遞給函數的變量名稱的任何雙引號。
在引用[]
之後,就不再需要了。還請注意使用!
而不是%
。感嘆號強制cmd.exe重新展開isit
。
啊...是的.. gotos ...嘿嘿。謝謝!我會在兩分鐘之內標記出來。謝謝! – nn2 2011-04-14 16:39:15
我複製粘貼上面的腳本,並得到與問題相同的問題。我刪除了(),它工作。也許這不應該是被接受的答案。 – 2011-04-15 02:10:46
感謝Vik,在發佈之前我還沒有測試過我的代碼(我目前在Linux上),結果如下...我剛更正了代碼。 – cedrou 2011-04-15 08:21:18