批处理文件,Vista x64,if和括号

7

在Windows上,一些批处理文件使用具有多行的IF语法,如下所示:

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

现在,Windows Vista x64决定将所有32位文件放在“C:\Program Files (x86)”下。不幸的是,每当您在多行IF中使用环境变量(如PATH)而没有加引号时,变量值中的括号会让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%出现的行,带有此内容的批处理文件将失败。这真是令人恼火。是否有解决方案?
1个回答

9

将所有的%SCALA_HOME%改为!SCALA_HOME!,并在文件顶部添加以下内容:

setlocal enableextensions enabledelayedexpansion

后者打开了“延迟变量扩展”,这意味着以!VAR!形式书写的变量只有在使用时才会被扩展,而不是在语句本身被解析时扩展。(根据我的有限经验,当然也包括这种情况,这意味着变量扩展更不容易被误解为实际的批处理文件语法结构。)感谢Patrick Cuff在评论中指出了这种更好的方法。
P.S.:正如您所发现的,cmd.exe批处理文件语言在许多方面都非常糟糕。如果您不能使用真正的脚本语言(例如,如果您的任务需要在其他计算机上执行),我强烈建议快速编写一个C/C++“脚本”来完成工作,并将其编译为.EXE。

1
如果延迟扩展确实解决了这个问题,你就不需要第二个批处理脚本了,只需在脚本顶部加上setlocal enableextensions enabledelayedexpansion即可。 - Patrick Cuff
我会尝试使用setlocal enableextensions enabledelayedexpansion。如果它起作用,我将需要另一个答案来设置为已接受。 - Daniel C. Sobral
希望这个对你有用。是不是有什么技术问题阻止你将我的答案标记为被接受的?如果是这样的话,不要担心。 - j_random_hacker
enabledelayedexpansion 仅适用于 !! 变量。这个解决方案有点奏效。它确实可以在 Vista 上修复,但我是否错误地认为它与非“%OS%”=“Windows_NT”系统不兼容? - Daniel C. Sobral
它应该在任何使用cmd.exe的系统上运行。仍在使用command.com(例如Win9x)的系统在其批处理语言中根本没有多行IF语句。 - j_random_hacker

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接