为什么CALL命令不能执行括号括起来的命令?

时间:2014-06-25 20:37:42

标签: batch-file cmd

在命令提示符和.bat文件中,行为都是相同的。

@echo off

:: the echo that will never be
call(echo echo echo)

:: its the same with non-cmd internal commands
call ( notepad.exe )

:: and even with a code that should fail
call(gibberish)

:: moreover the execution is successful
call (gibberish)&&echo %errorlevel%

:: though there's some parsing done
call(this will print call help because contains "/?"-/?)

:: and will detect a wrong syntax of some parsed-before-execution commands
call ( if a==)

:: and this too
call (%~)

:: same with labels
call(:label)
call(:no_label)
:label

According to the microsoft documentation

Using multiple commands and conditional processing symbols - (command1 & command2) Use to group or nest multiple commands.

Here's the CALL help page. - 因此,只要不使用重定向符号,语法就是非法的。

CALL解析器中的更多错误 - here

2 个答案:

答案 0 :(得分:2)

在命令提示符窗口cmd.exe /?中输入并查看上次显示的属于文件完成页面的最后一段:

The special characters that require quotes are:  
     <space>  
     &()[]{}^=;!'+,`~

因此所有带有这些特殊字符的字符串必须用双引号括起来。

由于文件完成由cmd.exe完成,因此可以预期对整个命令行以及批处理文件中的行进行类似的解析。

可以使用例如

call "( Notepad.exe )"

当然会导致错误消息,因为Windows无法找到名为( Notepad.exe )的可执行文件来调用。

我在一小时前herephd443322的有趣评论中了解到,cmd.exe解析的行与所有其他应用程序不同。

由于这个问题很可能永远不会被能够访问cmd.exe源代码的程序员阅读,所以我们永远不会得到解释为什么这些示例命令被解释为我们在执行它们时可以看到的。

答案 1 :(得分:2)

我认为将括号解释为表达式的分隔符的唯一命令是FOR,IF和SET / A

添加新行可能看起来很有希望:

Call (
 Echo Hello
)

但如果您尝试运行

Call (

实际上正在尝试运行命令(.cmd 如果您尝试创建名为(.cmd的批处理文件,那么您实际上可以使用

调用它
Call "("

引号是必需的,因为(是一个“特殊”字符。

在PowerShell中,可以在更多地方使用括号,如果在CMD和PowerShell之间切换,可能会造成混淆

(2+3)

将在PowerShell中返回5,但只是在CMD中出错。