Пакетные файлы, Vista x64, если и скобки

Некоторые пакетные файлы в Windows используют синтаксис IF с несколькими строками, как показано ниже:

if var==rule (
  some comands
) else (
  else commands
)

Теперь Windows Vista x64 решила поместить все 32-битные файлы в папку «C:\Program Files (x86)». К сожалению, всякий раз, когда вы используете переменную среды (такую ​​как PATH) внутри многострочного оператора IF без кавычек, круглые скобки внутри значения переменной сбивают с толку IF, прерывая пакетный файл. Например:

if "%OS%"=="Windows_NT" (
  @setlocal
  call :set_home
  set _ARGS=%*
) else (
  set _SCALA_HOME=%SCALA_HOME%
  rem The following line tests SCALA_HOME instead of _SCALA_HOME, because
  rem the above change to _SCALA_HOME is not visible within this block.
  if "%SCALA_HOME%"=="" goto error1
  call :set_args
)

Пакетный файл с этим завершится ошибкой, даже если строка, в которой появляется %SCALA_HOME%, не будет выполнена. Это довольно раздражает. Есть ли решение для этого?


person Daniel C. Sobral    schedule 10.01.2009    source источник


Ответы (1)


Замените все экземпляры %SCALA_HOME% на !SCALA_HOME! и добавьте следующее вверху файла:

setlocal enableextensions enabledelayedexpansion

Последний включает «отложенное раскрытие переменных», что означает, что переменные, записанные в форме !VAR!, не раскрываются до тех пор, пока они не будут использованы, а не при разборе самого оператора. (По моему ограниченному опыту и, конечно же, в данном случае это означает, что раскрытие переменных с меньшей вероятностью будет неправильно истолковано как синтаксическая конструкция реального пакетного файла.) Спасибо Патрику Каффу за указание на этот лучший способ сделать это в комментарии.

P.S.: Как вы заметили, язык пакетных файлов cmd.exe во многих отношениях ужасно неисправен. Если вы не можете использовать подлинный язык сценариев (например, если вашу задачу необходимо выполнять на других компьютерах), я бы настоятельно рекомендовал создать быстрый «скрипт» C/C++, который выполняет эту работу, и скомпилировать его в .EXE.

person j_random_hacker    schedule 10.01.2009
comment
Если отложенное развертывание действительно решает эту проблему, вам не понадобится второй пакетный скрипт, просто поставьте setlocal enableextensions enabledelayedexpansion в начале вашего скрипта. - person Patrick Cuff; 10.01.2009
comment
Я попробую использовать setlocal enableextensions enabledelayedexpasion. Если это сработает, мне понадобится другой ответ, чтобы установить его как принятый. - person Daniel C. Sobral; 12.01.2009
comment
Надеюсь, это сработает для вас. Есть ли какая-то техническая особенность, которая мешает вам отметить мой ответ как принятый? Если это так, не беспокойтесь об этом. - person j_random_hacker; 14.01.2009
comment
enabledelayedexpansion работает только для !! переменные. Это решение работает, вроде. Это, безусловно, исправляет это в Vista, но я ошибаюсь, предполагая, что это будет несовместимо с системами, отличными от %OS% = Windows_NT? - person Daniel C. Sobral; 17.01.2009
comment
Он должен работать в любой системе, использующей cmd.exe. Системы, которые все еще используют command.com (например, Win9x), в любом случае не имеют многострочных операторов IF в своем пакетном языке. - person j_random_hacker; 17.01.2009