为啥 cmd.exe 以不同方式解析插入符号
Posted
技术标签:
【中文标题】为啥 cmd.exe 以不同方式解析插入符号【英文标题】:Why cmd.exe parses caret differently为什么 cmd.exe 以不同方式解析插入符号 【发布时间】:2020-07-03 11:56:45 【问题描述】:我有以下命令和一个输出接收到的参数的简单程序。
第一个命令行printer.exe arg1 \" ^" arg2
拆分为printer.exe
、arg1
、"
和^ arg2
,第二个命令行printer.exe arg1 ^"arg2
拆分为printer.exe
、arg1
和arg2
。我的问题是,为什么在第二个命令中会跳过插入符号 ^
?
谢谢!
【问题讨论】:
嗯,这在很大程度上取决于printer.exe
如何解析它的参数。您是否在 Windows 命令提示符窗口 (cmd.exe
) 中执行此操作?
是的,printer.exe
在cmd.exe
中执行,参数由 CRT 解析,我只打印它们。
对于cmd.exe
,\
没有任何特殊意义,只有^
是转义字符;引用禁用特殊字符识别并因此转义;所以从左到右阅读,你的第一个例子结果是printer.exe arg1 \" ^" arg2
(不变),你的第二个例子是printer.exe arg1 "arg2
(你转义了她的引用);现在它取决于printer.exe
如何处理这些命令行...
【参考方案1】:
程序参数有很多问题。
要理解它们,您需要知道如何解析行。
首先该行由 cmd.exe 解析。 有很多规则(和阶段),但在你的情况下只有两个相关的。
每个引号切换quoted-mode
,在引号模式下,特殊字符失去special
的含义
插入符号转义下一个字符,插入符号本身将被删除。 插入符号也可以转义引号,以避免激活引用模式。 这仅适用于不带引号的模式,引号内的插入符号失去其特殊含义。
反斜杠对 cmd.exe 没有特殊含义。
对于您的示例,cmd.exe 会将它们解析为:
printer.exe arg1 \" ^" arg2
-> printer.exe arg1 \" ^" arg2 --- The caret is inside quotes
printer.exe arg1 ^"arg2
-> printer.exe arg1 "arg2 --- The caret was outside quotes
在 Windows 上,每个 program.exe
负责将命令行拆分为参数,尽管对于 linux,shell 决定如何拆分参数。
windows 程序的后果是: 一团糟!
您需要了解每个程序的规则,了解如何将行拆分为参数。 有些程序的规则支持反斜杠或双双引号,有些带有单引号,有些则不能构建任意参数。
更多解释How does the Windows Command Interpreter (CMD.EXE) parse scripts?
【讨论】:
在第一种情况下,应该切换quoted-mode
的插入符号被 `` 转义,那么为什么插入符号被认为是在引号内?
@tairqammar 在第一种情况下,第一个引号(带有反斜杠的那个)激活引用模式,因此插入符号失去任何特殊含义,第二个引用再次禁用引用模式
反斜杠不会转义 cmd
解析器中的任何内容(在将其转发给应用程序之前处理该行)。它“只是一个普通字符”(但应用程序可以区别对待)以上是关于为啥 cmd.exe 以不同方式解析插入符号的主要内容,如果未能解决你的问题,请参考以下文章
为啥debug编译可以通过,release就无法解析外部符号
Typescript模块在同一个文件中以不同方式解析'rxjs'
为啥 std::istringstream 在三元 (?:) 运算符中的解析方式似乎与 std::ifstream 不同?