Как экранировать переменные с круглыми скобками внутри предложения if в командном файле? - PullRequest
22 голосов
/ 19 октября 2011

Запуск этого командного файла

@echo off
set a=some value with (parentheses) inside
if 1 == 1 (
    set PATH=%a%
)

дает inside was unexpected at this time. ошибку.

Как экранировать a переменную, чтобы избежать этой ошибки?

Ответы [ 4 ]

27 голосов
/ 25 октября 2011

Вы можете использовать два разных способа

Используйте расширенный синтаксис set с кавычками set "var=content" установит var с содержимым, Контент цитируется, поэтому специальные символы не создают проблем, и он использует контент до последней цитаты (без самой цитаты)

@echo off
set a=some value with (parentheses) inside
if 1 == 1 (
    set "PATH=%a%"
)

Используйте отложенное расширение (например, ответ shf301), но также перенесите значение в основную область.

@echo off
setlocal enabledelayedexpansion
set a=some value with (parentheses) inside
if 1 == 1 (
    set "localScope_PATH=!a!"
    rem now transfer it to the global scope
    FOR /F "delims=" %%A in ("!localScope_PATH!") DO (
       endlocal
       set "path=%%A"
    )
)

В этом случае расширенный синтаксис set не требуется, я использовал его только для того, чтобы избежать скрытых пробелов в конце строки.

EDIT: Могу ли я совместить это с setlocal EnableDelayedExpansion и использованием! вместо% ленивый оценить значение переменной? Когда я попробовал, я получил)! было неожиданно в это время.

Можно, но это непродуктивно, как

@echo off
Setlocal EnableDelayedExpansion
set a=some value with (parentheses) inside
if 1 == 1 (
    set PATH=!a:^)=^^^)!
    set path
)

Тогда ваш путь содержит знаки перед ) C:\programs (x86^)

Чтобы понять, как работает расширение, вы можете прочитать SO: Как интерпретатор сценариев команд Windows (CMD.EXE) анализирует сценарии?

EDIT2: больше проблем с путем (с кавычками)
Согласно этому вопросу может возникнуть другая проблема с круглыми скобками, когда путь содержит кавычки.

Пример
path="C:\Program Files (x86)";C:\Program Files (x86)\Skype

Это разрешено, даже если здесь нет необходимости использовать кавычки, но это разрушает расширенный синтаксис SET, так как теперь set "newPath=%path%" расширяется до

set "newPath="C:\Program Files (x86)";C:\Program Files (x86)\Skype"

Теперь, по крайней мере, одна скобка не заключена в кавычки и может разбить командный блок.

Но вы можете просто удалить все кавычки из переменной пути, как сказано, кавычки здесь не нужны.

set "newPath=%path:"=%"
4 голосов
/ 25 октября 2011

Проблема ) в %a% здесь. Вы можете просто сделать некоторую замену, чтобы избежать ).

@echo off
set a=some value with (parentheses) inside
if 1 == 1 (
    set PATH=%a:)=^)%
)
2 голосов
/ 25 октября 2011

Скобки и переменные всегда сложно смешать.Вместо этого используйте подпрограмму.

@Echo Off
Set a=some value with (parentheses) inside
If 1 == 1 Call :SetPath
Echo %Path%
Exit /B

:SetPath
Set "Path=%a%"
SetX "Path" "%a%"
Exit /B

Я установил переменную дважды, один раз, используя Set для текущего сеанса оболочки, и один, используя SetX , чтобы установить его системно.широкий для будущих сессий оболочки.Удалите либо, если они не нужны.

2 голосов
/ 25 октября 2011

Использование отложенного расширения исправит это:

@echo off
setlocal enabledelayedexpansion
set a=some value with (parentheses) inside
if 1 == 1 (
    set PATH=!a!
)

Без отложенного расширения блок if (от if до конечного ), сначала заменяется% a%, а затем анализируется блоки запустить. С отложенным расширением! a! не раскрывается после разбора блока. Поэтому логика синтаксического анализа не увидит) в a и не вызовет проблем.

...