为什么可将cmd和/c放在同一对引号中执行,cmd.exe却不行?
cmd.exe 命令行引号解析规则
核心解析流程
cmd对命令行的解析分为两个核心阶段,所有观测到的测试现象都可以用以下规则解释:
阶段1:可执行文件定位
cmd从命令行起始位置开始识别要运行的程序,规则如下:
- 无引号开头时,读取到第一个空白字符(空格、制表符)为止的内容作为可执行文件路径
- 有引号开头时,匹配到下一个非转义的双引号,将引号包裹的完整内容作为可执行文件路径,查找该文件是否存在:
- 若路径包含
.exe/.com等可执行后缀,查找失败则直接报错「系统找不到指定的路径」,对应测试用例"cmd.exe /c" echo 1报错的现象 - 若路径不包含可执行后缀,查找失败会触发cmd的特殊拆分逻辑:将引号内的内容按空格拆分,取第一段为程序名,剩余部分作为启动参数,对应测试用例
"cmd /c" echo 1可以正常执行的现象
- 若路径包含
- 自定义的
cmd.exe仅在cmd /c echo 1场景被调用,是因为该场景下定位的可执行文件名为cmd,优先匹配当前目录下的cmd.exe;而"cmd /c"场景触发拆分逻辑后调用的是系统路径下的原生cmd.exe,不会查找当前目录的自定义程序
阶段2:/c//k参数后的命令解析
当确定调用原生cmd.exe且携带/c或/k参数时,cmd会对后续的待执行命令做特殊解析,遵循双引号奇偶计数规则:
- 从
/c后的第一个字符开始计数,每遇到一个非转义双引号,计数+1 - 计数为奇数时,后续遇到的所有字符(包括空格)都被当作普通命令内容保留
- 计数为偶数时,后续遇到的空白字符会被当作参数分隔符丢弃
- 观测到的前导空格现象,对应计数为奇数时,右引号和后续命令之间的空白被当作命令内容保留:
- 例:
"cmd /c"echo 1的全句引号总数为2,拆分后/c后接的内容是echo 1(前面多了一个被保留的空格),执行echo 1就会输出前导空格 - 当新增额外的引号把总计数凑为偶数时,多余的空白会被当作分隔符丢弃,就不会出现前导空格
- 例:
- 测试用例
"c"m"d" "/"c"echo 1进入交互模式,是因为引号拆分后无法正确识别/c参数,cmd启动后没有需要执行的命令,直接进入交互状态
内容的提问来源于stack exchange,提问作者Tuff Contender
相关产品推荐
相关产品推荐

