我有一个批处理文件,它有自己的短路径名(以消除空格,这是gcc不喜欢的),以便在后续命令中使用:
set base=%~d0%~sp0
这在大多数情况下都能很好地工作;例如,如果批处理文件位于C:\Program Files中,则%base%的值将为C:\PROGRA~1,并且gcc为happy。
但是,如果批处理文件位于名称中带有“&”的目录中,则该命令无效。如果批处理文件位于名为“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 off
set base=%~d0%~sp0
echo %base%
如果在名为“C:\Here & There”的目录中执行,我希望输出为
C:\HERE&T~1
没有引号或其他无关的输出。
以下是使用CMD.EXE作为shell时的实际输出:
'T~1\' is not recognized as an internal or external command,
operable program or batch file.
C:\HERE
如果我将@echo off
改为@echo on
,以在执行命令时显示这些命令,我会得到以下结果(其中“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
2条答案
按热度按时间oxcyiej71#
由于引号不应是值的一部分,因此正确的SET命令应为
djp7away2#
有两个问题,第一个是
SET
命令中的扩展。可以通过在表达式两边加上引号来避免。
第二个问题是
echo
,它也可以通过引号来避免。但引号也是可见的。
在批处理文件中,这可以通过延迟扩展来解决:
但在命令行中,延迟扩展模式不能通过
setlocal
进行修改,只能在cmd.exe
启动时通过/v:on
选项进行设置