为什么在批处理和cmd中无法调用“IF”和“FOR”?

6
说实话,我不希望在这里得到一个令人满意的答案。这些命令无法调用,就是这样(据我所知,唯一不能与call一起使用的命令)。 以下是几个例子及其输出:
C:\Windows\system32>call @if a==a echo called 
',' is not recognized as an internal or external command,
operable program or batch file.

C:\Windows\system32>call (@if a==a echo called)
';' is not recognized as an internal or external command,
operable program or batch file.

C:\Windows\system32>call if a==a echo called
'if' is not recognized as an internal or external command,
operable program or batch file.

C:\Windows\system32>call for  %a in (1) do @echo called
'for' is not recognized as an internal or external command,
operable program or batch file.

C:\Windows\system32>call @for  %a in (1) do @echo called
'+' is not recognized as an internal or external command,
operable program or batch file.

C:\Windows\system32>call (@for  %a in (1) do @echo called)
';' is not recognized as an internal or external command,
operable program or batch file.

我有一些疑虑,IF和FOR是否真正是“实际”命令——它们只是决定将命令提示符控制传递到它们后面的行(或括号块),这会导致调用混乱。不过,即使在调用FOR或IF时存在语法错误,也会被检测出来:

C:\Windows\system32>call (@if a= echo called)
= was unexpected at this time.

C:\Windows\system32>call (for %a (1) do echo called)
(1 was unexpected at this time.

所以至少解析工作已完成。

3个回答

8
你说得很对。 FORIFREM不是普通的内部命令(但对于REM,也存在一个普通的内部版本)。 它们使用自己特殊的解析器(每个解析器都不同)。 看起来这些命令被翻译成一种令牌。 因此出现了这样意外的错误消息(还有更多可能的字符),错误/令牌字符也取决于Windows版本(如果我记得正确的话)。 可能CALL命令只看到原始命令的令牌化数据。 命令块根本不适用于call命令,而&|<>也不能按预期工作。
call (a^|a)

搜索命令/令牌2,因此如果您创建了名为2.bat的批处理文件,则可以使用call (a^|a)启动它。

有关CALL的更多信息
Dostips:CALL me, or better avoid call
Dostips:Limit CMD processing to internal commands, safer and faster?


4

毕竟,我们可以调用IF和FOR等语句……或者几乎所有的语句;

    @echo off

rem :: this will produce an error
rem if a equ a

rem :: And this too
rem call if a equ a rem

rem :: But this will not!!!
call if a equ a

rem :: This will not too ((\but in command prompt single % is enough)
call for %%%%a in (.) do

rem :: And this
call if a equ a for %%%%a in (.) do if 1 equ 1  for %%%%a in (.) do if c==c

rem :: And this
call if a equ a for %%%%a in (.) do if 1 equ 1 for %%%%a in (.) do if c==c ( rem rem rem echo something

尽管我看不到它的用途。

3
你测试了很多东西,不仅仅是这些,这让人印象深刻。因此你发现了很多有趣的事情。 - jeb

1
这是一种可行的方法: 调用cmd.exe /c,如果a等于a,则输出“called”。

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