注册 登录  
 加关注

网易博客网站关停、迁移的公告:

将从2018年11月30日00:00起正式停止网易博客运营
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

为着理想勇敢前进

 
 
 

日志

 
 

Windows命令行参数的转义  

2009-10-15 21:37:21|  分类: 默认分类 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

Windows命令行参数的转义分为两个步骤,第一个步骤是cmd解析你输入的字符串决定要启动哪些进程,进程之间是否要标准输入输出重定向等等;第二个步骤是CRT把传入进程的命令行字符串切成多个参数,填好argc和argv传入main。

如果一个程序不是被cmd启动的,而是通过快捷方式或者bash等别的shell启动的,或者干脆直接调用API CreateProcess,那么第一个步骤可以无视;如果一个程序并不使用argc、argv,而自行调用GetCommandLine等Windows API,则第二个步骤可以无视。

第一个步骤中,| ^ " &等字符是特殊字符。如果特殊字符出现在双引号外,需要被转义。但如果出现在双引号中,就不需要也不能被转义。转义时,^^代表^^|代表|^"代表"等等

第二个步骤的具体实现取决于CRT,在Windows XP中用得最广泛的CRT是msvcrt.dll。Windows XP附带的系统程序大都使用了它,用VC6或mingw的gcc编译的程序也使用这个CRT。我看了一下VC6附带的源码,切参数这件事情的规则相当复杂。

首先是空格和tab如果不在双引号,就会被当作参数的分隔符,而双引号引住的空格和tab代表空格tab字符本身。

其次是连写双引号的特殊处理。如果想要把双引号作为参数内的字符,那么至少要连写两个双引号:""。当他遇见连续的两个双引号时,他会把其中一个双引号作为双引号字符,另一个双引号作为引用范围的开始或结束。也就是说,如果你已经在引号中了,连写2个双引号的话,就会产生一个"字符,并且关闭引用。要想产生一个"字符但不改变引用状态,就需要连写三个双引号"""

最变态的是用反斜杠(即\)转义的规则。对于n个反斜杠外加一个双引号会被转义。如果n为奇数,那么会被转义成(n-1)/2个\字符外加一个"字符。如果n为偶数,那么会被转义成n/2个\字符,然后再进入或结束引用范围。而如果反斜杠后面并不跟随双引号,反斜杠就不转义。

值得注意的是,因为cmd和CRT对双引号字符的转义规则并不一致,所以cmd和CRT对于某个字符是否被引用的判断也是不一致的。比如说,如果你想进行一次Subversion提交,注释中写上

hello " | " |   " | "  world
,那你得写:
svn commit -m "hello """ ^| """ |   """ ^| """  world"

注意,其中某些|必须要转义,而另一些则必须不转义。

上面说的还仅仅是msvcrt.dll切参数的规则,这个规则和cygwin的CRT是不一致的,也就是说,如果你在cmd中要调用cygwin编译的程序,那么转义规则又不一样。幸好这种情况并不是很多,用cygwin的话,就用bash好了,至少全世界的bash解析参数的方式都一样。

  评论这张
 
阅读(1974)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018