Кавычки обычно неправильно используются в пакетных файлах DOS.В отличие от сценариев оболочки UNIX, пакетный язык 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
пусто.Часто пакетные файлы останавливаются из-за пустых переменных:
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
удаляет все двойные кавычки вокруг имени переменной, передаваемой функции.
После удаления кавычек []
Трюк больше не требуется.Обратите внимание также на использование !
вместо %
.Восклицательные знаки заставляют cmd.exe повторно развернуть isit
.