批处理脚本在块中以不同方式处理变量吗

时间:2016-03-16 20:27:50

标签: batch-file

我正在运行一个更新某些变量的批处理文件,特别是%PATH%。我的环境有一个已知的错误,即引用%PATH%中的目录,即

PATH=c:\windows;...;"c:\program files\foo"\bin;c:\program files\...

我有一个附加到PATH的脚本。当我在IF块内执行此操作时,出现错误,例如:

IF "1"=="1" (
  SET "PATH=%PATH%;c:\foo"
)

给出错误

  

\微软此时出人意料。

其中\Microsoft显然是%PATH%。

中某个目录的片段

如果SET不在条件块内,我不会收到错误。这是为什么?

编辑:似乎这与PATH还包含括号的事实有很大关系。以下是此问题的更好示例:

C:\temp>SET "FOO=C:\Program Files (x86)\;foo"
C:\temp>ECHO %FOO%
C:\Program Files (x86)\;foo
C:\temp>IF "1"=="1" ( ECHO %FOO% )
\ was unexpected at this time.
C:\temp>IF "1"=="1"  ECHO %FOO%
C:\Program Files (x86)\;foo

所以我的问题是,如果它在paren-delimited块中,它为什么会破坏?

4 个答案:

答案 0 :(得分:2)

JosefZ properly identified the problem with ) in the path,但他建议的删除所有引号的解决方案并不安全。

PATH变量中的任何路径都可能包含;!&)和/或^,所有这些都可能导致各种问题使用正常的%PATH%扩展时。

可能会有一些引用&)等的路径,以及一些带有问题字符的未加引号的路径,因此%PATH%"%PATH%"都可能失败。

扩展PATH的唯一保证安全方法是通过延迟扩展,但您希望新值在ENDLOCAL中存活。该怎么办? 。 。 。
。 。 。 FOR / F和延迟扩展切换到救援: - )

if "1"=="1" (
  setlocal enableDelayedExpansion
  for /f "eol=: delims=" %%P in ("!path!") do (
    endlocal
    set "path=%%P;c:\foo"
  )
)

通过set path=%path%;c:\foo
等代码简单实现PATH扩展 或set "path=%path%;c:\foo"猖獗,但不安全。总的来说,人们并没有意识到PATH管理所带来的微妙复杂性。

如果您曾尝试修改可以释放到野外的批处理脚本中的PATH变量,那么您应该始终使用我上面所示的安全方法。

如果您想要有条件地将路径追加到PATH,当且仅当路径不存在时,问题变得更加复杂。请参阅How to check if directory exists in %PATH%?以获取潜在问题列表,以及相当强大的解决方案。

答案 1 :(得分:0)

SET "PATH=%PATH:"=%;c:\foo"

应该解决问题,因为这些问题是无关紧要的

警告:如果路径条目包含“;”,则可能不是这样。在这种情况下,您应该将目录重命名为合理的。

答案 2 :(得分:0)

只需删除路径变量设置中的外引号即可。无论如何,他们都不是必需的。当然不是在这种情况下,你在那些引号内部使用引号。引号应该在你的路径变量中,而不是在整个事物之外。

SET PATH=%PATH%;c:\foo

为了进一步说明应该如何做,这里还有一些其他的例子来澄清...

SET PATH=%PATH%;C:\foo
SET PATH=%PATH%;"C:\Some Folder With Spaces In It"
SET PATH=%PATH%;"C:\Program Files\Foobar Inc Software"

但永远不会......

SET "PATH=%PATH%;SomePath"

答案 3 :(得分:0)

你说得对,这更多地与PATH也包含括号的事实有关。下一个示例明确地显示了该问题:

==> ( set "varName=var"value(s) with"space(s) and"right parentheses"" )
with"space(s) and"right was unexpected at this time.

==> ( set varName=var"value(s) with"space(s) and"right parentheses" )
and"right parentheses" was unexpected at this time.

==>

阅读How does the Windows Command Interpreter (CMD.EXE) parse scripts?的答案以获得解释。

我可以看到唯一的解决方案:通过删除所有path双引号来校正(调整)"变量一次,如下所示(检查用户变量path是否存在) 。需要重新启动。

adjust path variable