Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1322389
  • 博文数量: 482
  • 博客积分: 13297
  • 博客等级: 上将
  • 技术积分: 2890
  • 用 户 组: 普通用户
  • 注册时间: 2009-10-12 16:25
文章分类

全部博文(482)

文章存档

2012年(9)

2011年(407)

2010年(66)

分类: LINUX

2011-10-04 22:24:18

作者:xialulee
最初发布于:2011年3月7日,http://blog.sina.com.cn/xialulee
    因为有msys这样的项目,所以在Windows下我们也可以方便地使用bash(当然,有一些特性诸如process substitution在Windows下无法使用,因为Windows下没有Linux中的那种fifo)。因为有了bash这么好用的东西,我们很想把它和Windows下的vim,ipython这样的软件挂钩,Windows下的vim和ipython默认调用cmd.exe来执行外部程序。用过bash的人大概都会觉得cmd.exe实在是有点……不说别的,因为cmd.exe没有方便的command substitution(没有方便的,但是确实有,可以用for语句实现command substitution的功能,stackoverflow上有人专门讨论过这个问题),用起来感觉很受限制。而且经常在Windows和Linux两种平台上工作的人,很希望使用相同的方式完成类似的工作。
    因为vim可以使用set shell和set shellcmdflag来修改vim调用的shell,因此今天我就试了试,在_vimrc中加入如下两行:
set shell=E:/Program/MinGW/msys/1.0/bin/sh.exe
set shellcmdflag=-c
就可以在vim中通过
:!command
来调用msys的sh.exe执行命令了。
    大概故事就应该这样美好的结束了,其实不然。真正的故事才刚刚开始,而且实际上是一个伤心的故事。
    因为vim会调用msys的bash来执行命令,所以我们就会以bash的方式来输入指令,问题产生了。例如,我们在vim中输入:
:%!awk 'BEGIN{print "abc"}'
期望abc会出现在编辑的文本之中,结果却什么也没有发生!难道输入的命令有问题吗?于是我们在Ubuntu下试了试:


明明很好使嘛。既然我们已经将vim的shell通过set shell设置成了msys的bash,为什么和Linux下的vim具有不同的行为呢?经过一番研究,终于发现了问题所在:
    设置了shell和shellcmdflag之后,Windows的vim在执行指令时,会将输入的指令两端加上引号,如下:


而Windows在传递命令行参数时有这样一个特点:首先会以贪婪的方式匹配双引号对,然后将双引号对中间的双引号删除,引号删除后,对于awk而言,abc就不是一个字符串,而是变量名,这个变量没有初始化,awk就会默认把它初始化为空串,所以最终什么也没有发生。但是经过转义的双引号则会解释成双引号,所以如果想得到期望的结果,在Windows下就得输入:
:%!awk 'BEGIN{print \"abc\"}'
在引号前面加上\。效果如下:


这就导致了和Linux的vim操作上的差异,因为Linux下这种情况双引号不需要转义:


也就是说,虽然通过set shell使Windows下的vim可以调用bash来执行命令,但是仍然无法让Windows的vim和Linux的vim具有完全相同的调用外部命令的方式。
    有个老程序员说过:非常相似,但有几分不同,其实是蛮危险的。所以最终我决定不修改shell,还是让vim使用默认的cmd.exe。
 
====
阅读(971) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~