使用此程序 ( cs.exe
):
class Program
{
static void Main(string[] args)
{
foreach (var item in args)
{
Console.WriteLine(item);
}
}
}
Run Code Online (Sandbox Code Playgroud)
并运行:
> cs.exe go\to\a_path
go\to\a_path
> cs.exe "go\to\a path"
go\to\a path
> cs.exe "go\to\a path\"
go\to\a path"
> cs.exe 'go\to\a path\'
'go\to\a
path\'
Run Code Online (Sandbox Code Playgroud)
这意味着如果你的路径有一个空格所以你引用它,要非常小心不要\
在末尾放一个尾随,否则你的程序可能无法处理它,因为它"
在末尾错误地包含了 a 。单引号更奇怪!
PowerShell 表现出类似的行为,但没有单引号和双引号之间的区别。
我如何理解这种行为?在 cmd 中评估反斜杠的基本规则是什么,以便可以一致地解释?
由于您不是调用内部cmd
命令,而是调用可执行文件,因此此行为不是由cmd
命令行参数解析器例程引起的。在 Windows 中,程序不接收集合/数组/参数集,而是一个包含所有参数的字符串,并且每个程序都将此字符串标记化以获得每个元素。这通常由编译器包含的例程完成,这些例程隐藏此操作并向代码公开处理参数的更简单方法。
C 命令行参数解析器的文档指出
参数由空格分隔,空格或制表符。
被双引号包围的字符串被解释为单个参数,而不管其中包含的空格。带引号的字符串可以嵌入到参数中。请注意,插入符号 (
^
) 不被识别为转义字符或分隔符。以反斜杠 , 开头的双引号
\"
被解释为文字双引号 ("
)。反斜杠按字面解释,除非它们紧跟在双引号之前。
如果偶数个反斜杠后跟一个双引号,则
\
在 argv 数组中为每对反斜杠 (\\
)放置一个反斜杠 ( ),并且双引号 ("
) 被解释为字符串分隔符。如果奇数个反斜杠后跟一个双引号,则
\
在 argv 数组中为每一对反斜杠 (\\
)放置一个反斜杠 ( ) 并且双引号被剩余的反斜杠解释为转义序列,从而导致"
要放置在 argv 中的文字双引号 ( )。
还有一组未记录/非官方规则(如何解析命令行参数)
- 在双引号块之外,a
"
开始一个双引号块。- 在双引号块中 a
"
后跟一个不同的字符(不是另一个"
)结束双引号块。- 在双引号块中 a
"
紧跟另一个"
(即""
)导致将单个"
添加到输出中,并且双引号块继续。
该.Net
分析参数的规则只是这些规则推导。如果您需要不同的行为,那么您应该使用该Environment.CommandLine
属性来检索完整的命令行字符串并编写您自己的解析代码。