为啥 cmd.exe 以不同方式解析插入符号

Posted

技术标签:

【中文标题】为啥 cmd.exe 以不同方式解析插入符号【英文标题】:Why cmd.exe parses caret differently为什么 cmd.exe 以不同方式解析插入符号 【发布时间】:2020-07-03 11:56:45 【问题描述】:

我有以下命令和一个输出接收到的参数的简单程序。 第一个命令行printer.exe arg1 \" ^" arg2 拆分为printer.exearg1"^ arg2,第二个命令行printer.exe arg1 ^"arg2 拆分为printer.exearg1arg2。我的问题是,为什么在第二个命令中会跳过插入符号 ^

谢谢!

【问题讨论】:

嗯,这在很大程度上取决于printer.exe 如何解析它的参数。您是否在 Windows 命令提示符窗口 (cmd.exe) 中执行此操作? 是的,printer.execmd.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 不同?

为啥我无法解析符号“R”? [复制]

c# 借助cmd命令解析apk文件信息

为啥我会收到“无法解析符号 'CreatePerOwinContext'”?