【问题标题】:Windows batch file: pathname with "&" interpreted as two commandsWindows 批处理文件:带有 \"&\" 的路径名被解释为两个命令
【发布时间】:2022-11-13 18:17:46
【问题描述】:

我有一个批处理文件,它有自己的短路径名(以消除 gcc 不喜欢的空格)用于后续命令:

set base=%~d0%~sp0

这适用于大多数情况;例如,如果批处理文件位于 C:\Program Files 中,则 %base% 的值将是 C:\PROGRA~1,gcc 很高兴。

但是,如果批处理文件位于名称中带有“&”的目录中,则它不起作用。如果它位于名为“C:\Here & There”的目录中,则上面的命令将扩展为

set base=C:\HERE&T~1\

这被视为两个命令,产生错误消息'T~1\' is not recognized as an internal or external command, operable program or batch file.

如果我在它周围加上引号:

set base="%~d0%~sp0"

然后命令起作用,%base% 的值为"C:\HERE&T~1\"(包括引号)。但是,当我使用它来构建 Java 类路径时,引号会进一步破坏文件中的其他内容:

java -cp .;"C:\HERE&T~1\"Jars\* foo

上面写着“系统找不到指定的文件”(与类路径中的"C:\HERE&T~1\"Jars\* 相关)。

任何人都可以提出解决这个微软混乱的方法吗?

[编辑]

根据下面 Mofi 的要求,这是一个最小的可重现示例批处理文件:

@echo on
set base=%~d0%~sp0
echo %base%

请注意开头的“@ECHO ON”,因此命令将在执行之前显示。

如果这是在名为“C:\Here & There”的目录中执行的,我希望输出为

C:\HERE&T~1

没有引号或其他无关的输出。

这是使用 CMD.EXE 作为 shell 时的实际输出(其中“C:\Here & There>”是提示符,后面是执行前回显的实际命令):

C:\Here & There> set base=C:\HERE  & T~1\
'T~1\' is not recognized as an internal or external command,
operable program or batch file.

C:\Here & There> echo C:\HERE
C:\HERE

C:\Here & There>

【问题讨论】:

  • Windows 上的java.exe 是否支持自己的通配符,例如*?我不这么认为,但不确定。使用set "base=%~dp0"java.exe -cp ".;%base%Jars" foo 可以将批处理文件目录中的当前工作目录(.)和子目录Jars 定义为Java 文件foo 的类文件目录。
  • 是的,很多年了。从大约 1.4 开始的所有 Java 版本都支持这一点。去掉引号(并在名称中没有“&”的目录中运行它),它工作得很好。
  • 谢谢你提供信息。很高兴知道我的未来。我还没有安装 Java。由于标签,我发表了我的评论批处理文件.许多从 *nix 移植到 Windows 的应用程序依赖于 Linux/Mac shell 解释器对参数字符串中通配符模式的扩展,在启动应用程序之前,这些解释器将通配符模式参数字符串替换为文件系统条目的匹配列表。 Windows 命令处理器cmd.exe 根本没有这样的功能。由于这个原因,许多移植到 Windows 的 *nix 应用程序不能使用通配符模式。
  • 请打开命令提示符窗口,运行cmd /? 并阅读cmd.exe 的输出使用帮助。在最后一个帮助页面的最后一段中解释了有关文件/文件夹名称完成功能的最终信息,文件名(或任何其他参数字符串)包含一个空格或这些字符&()[]{}^=;!'+,`~(或密码中的<>|)必须包含在 " 中才能按字面解释。好吧,[] 老实说对 cmd.exe 不再有特殊含义。当我没记错时,方括号对 MS-DOS 3.x 的 COMMAND.COM 有特殊含义。
  • 是的,我很清楚这一点。我基本上是在问除了“......”之外还有什么方法可以压制他们的解释。我以为 Ben Voigt 搞定了(下图),但事实证明它只能在 CMD 以外的其他 shell 中工作。在标准批处理文件中似乎没有办法解决这个问题。

标签: windows batch-file


【解决方案1】:

由于引号不应该是值的一部分,正确的 SET 命令应该是

set "base=%~d0%~sp0"

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2019-10-31
  • 2023-03-28
  • 1970-01-01
  • 2012-09-29
  • 1970-01-01
  • 2014-06-04
  • 2011-04-28
  • 2012-12-10
相关资源
最近更新 更多