[20251208]vim插件bccalc_linux.vim使用问题2.txt
--//前天在linux下使用vim插件bccalc_linux.vim遇到的问题。虽然vim在linux与windows下自己都经常使用,linux下主要写sql语句以
--//及编程为主,在windows下写文档,该插件在linux下自己很少使用,今天遇到问题,感觉system函数调用存在许多问题。
:version
VIM - Vi IMproved 7.4 (2013 Aug 10, compiled Jun 10 2014 06:55:55)
Included patches: 1-160
Modified by <bugzilla@redhat.com>
Compiled by <bugzilla@redhat.com>
--//在linux下vim是随机安装,我很少升级,仅仅做一些简单定制,添加少量的插件。
--//理论讲10->16,16->10转换是可以做一些计算的。比如:
0xa+0x2
--//打入 \10 将16进制转换10进制。
0xa+0x2 = 12
--//相当于10+2=12
0xa / 0x3 = 3.33333333333333333333
0xa - 0x3 = 7
--//加减除都没有,而做乘法存在问题,主要乘除的运算基本没有遇到,问题也就没有暴露出来!
0xa * 0x2
--//打入\10 ,显示 0xa * 0x2 = (standard_in) 1: illegal character:
:registers e
--- Registers ---
"e 0xa * 0x2
--//"手工调试如下:
let preload = exists ("g:bccalc_preload") ? g:bccalc_preload : ""
let str="0xa * 0x2"
let str = toupper (str)
let str = substitute (str, "0x", "", "g")
let answer = system ("echo 'ibase=16 ;" . str . "' \| bc -l " . preload)
echo answer
--//显示如下:
20
--//手工执行没有问题。
--//无法定位该问题在哪里,*与^运算都存在问题。
set verbose=5
0xa * 0x2
--//打入\10,在提示行出现如下信息:
Calling shell to execute: "(echo 'ibase=16 ;A \* 2' | bc -l ) >/tmp/vVzpvLc/0 2>&1"
--//可以发现在脚本执行时转义* ,变成\* ,视乎问题定位在*运算符号上,但是执行如下:
10 * 2
--//打入\cc,在提示行出现如下信息:
Calling shell to execute: "(echo 10 \* 2 | bc -l ) >/tmp/vDqLL5F/0 2>&1"
--//而结果是正确的,显示20.
--//仔细检查发现前者有单引号而后者没有,linux下分号作为命令分隔,必须使用引号,windows下不需要引号:
d:\>echo ibase=16; A+2 | bc
12
--//存在分号,windows不会拆分2个命令。而linux不行:
$ echo ibase=16 ; A+2 | bc
ibase=16
bash: A+2: command not found...
$ echo 'ibase=16 ; A*2' | bc
20
--//问题在于连接字符串时,脚本会自动转义里面的bash shell字符。比如*,而手工逐条执行不会,有点类似windows的批处理问题。
--//而windows版本就没有这个问题,echo 的输出没有分号。
0xa * 0x2 = 20 --// 打入\10
10 * 2 = 0x14 --// 打入\16
--//知道原因就知道解决问题的方法:
if a:flag == 10
let str = toupper (str)
let str = substitute (str, "0x", "", "g")
"let answer = system ("echo 'ibase=16 ;" . str . "' \| bc -l " . preload)
let answer = system ("echo ibase=16 \\\;" . str . " \| bc -l " . preload)
"let answer = system ("echo -e ibase=16 \\\\n" . str . " \| bc -l " . preload)A
"let answer = system ("echo 'ibase=16 ;" . substitute(str, "\\", "", "g") . "' \| bc -l " . preload)
endif
--//以下三种方法都可以现实:
let answer = system ("echo ibase=16 \\\;" . str . " \| bc -l " . preload)
let answer = system ("echo -e ibase=16 \\\\n" . str . " \| bc -l " . preload)A
let answer = system ("echo 'ibase=16 ;" . substitute(str, "\\", "", "g") . "' \| bc -l " . preload)
--//最终选择第1种方法,就是删除单引号在;前面增加\\\。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/267265/viewspace-3105150/ ,如需转载,请注明出处,否则将追究法律责任。