批处理文件中出现意外的错误:“系统找不到指定的驱动器”。

22

我有一个批处理文件问题(Windows 7 x64)。我已经将它简化为以下内容(有两行空注释行;似乎是否有实际注释并不重要):

@echo off

if /i [%1]==[] (
    echo A
    ::
    ::
    echo B
)

将这段代码放入批处理文件中并不带任何参数运行,会产生以下输出:

A
The system cannot find the drive specified.
B

删除其中一行的 :: ,或者删除包围它的 if修复 了问题,这样您就可以获得预期的输出:

A
B

这里发生了什么事?为什么它要寻找驱动器?

编辑

非常感谢到目前为止的回复。所以我的问题归结为:

确定::是表示“注释开始”还是“驱动器号冒号”的规则是什么?

也许最好还是切换回使用REM添加注释,这样就不会存在歧义,但我确实发现::样式更易于阅读。

2个回答

29

这是在批处理代码块中的一个不太常见的影响。

在代码块中,一行标签始终需要具有相当不同的语法规则的第二行(对于第二行)。
SO:goto命令无效

第二行必须是一个命令或简单的标签,但不能是括号、双冒号或以括号附加的内部命令。

MC ND 解释说 : 在这里像正常的驱动器字母一样使用,那确实如此!
但只适用于第二行,即使你可以通过 subst :: C:\ 来抑制错误,该行也会像标签一样处理(你不能启动任何东西)。

subst :: C:\
(
:label
::\windows\system32\calc.exe
)

即使该行是标签,第二行也可以接受&

失败的示例

(
:Label at the end fails
)

(
:label
  ( 
    echo new Block fails
  )
echo ...
)

(
:label
:: Double colon fails
)

(
:label
echo( fails also, as now a file named "echo(" is searched for execution
)

现在正在工作的

(
::Works
:with a "normal" label in the second line
)

(
:But this label! & echo This will not echo'd
:but & echo You can see this !
)

(
:label
echo or a simple command works too
)

有时 :: 会被用作注释样式,如果你不在意次行,这可能会在块内部引起问题。

编辑:回答您的第二个问题

如何确定 :: 是指“注释开始”还是“驱动器字母冒号”的规则?

第一个 :: 总是表示注释或标签,在下一行它总是表示 驱动器字母冒号


2
正确。错误在第二个::上,正如你所说的原因。第一行是一个标签,第二行应该是一个有效的命令,而::可以被认为是有效的,因此它被执行了。是的,你可以使用start ::\windows\system32\calc.exe来启动某些东西。正如之前所评论的,系统的并非所有部分都能够处理它。 - MC ND

7

::是一个有效的驱动器。就像c:d:一样,但字母是:

因此,您的命令正在尝试从当前驱动器更改到驱动器::

示例:尝试subst :: c:\,然后dir ::\


+1,但是::不是一个“完全令人满意”的驱动器,没有参数的subst不会显示这个。 - Endoro
@Endoro,mountvol :: /Lmountvol c: /L。对我来说,两者都是同一个卷。但是,是的,并不是系统中的所有工具都能与其一起使用。 - MC ND
1
但为什么在两个 :: 之间插入 echo x 后代码就能正常运行? - jeb
+1 我已经测试过了,它确实抑制了第二行的语法错误。 - jeb

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