1. 背景介绍

自加入RedHat起,我就把家里的台式机(Ubuntu 16.04 LTS)的默认登录用户veli切换成了huanli, 主要是为了跟公司的电脑配置对齐以方便未来WFH,但引发了一个vim使用异常。在我的.vimrc中,有这样一段配置代码,

if has("autocmd")
" When editing a file, always jump to the last known cursor position.
autocmd BufReadPost *
\ if line("'\"") > && line("'\"") <= line("$") |
\ exe "normal g`\"" |
\ endif
endif " has("autocmd")

这段代码的作用就是记住前一次光标的位置,再次打开文件的时候自动跳转到那里。 这是一个非常有用的功能,对于喜欢使用vim的程序员来说。 当我切换成huanli用户后,这一功能莫名其妙的失灵了Orz。。。

2. 故障调试

201 - 基于vim不同版本的对比测试: vim版本应该是默认支持autocmd功能的,但为了排除是版本问题(当前版本是7.4.1689), 于是下载一个vim8.0的源码包,编译并安装到/usr/local, 发现问题依然存在。

202 - 基于不同host的对比测试: 在笔记本上使用同样版本的vim, 发现笔记本上工作正常,台式机上工作异常,于是判定vim版本(7.4.1689)没有问题,一定是台式机某种设置引发的异常。 操作步骤如下:

(1) 同时在笔记本和台式机的Terminal上用vim打开一个文件, e.g.

$ vim /tmp/foo.c

在vim里执行

autocmd BufReadPost *

比较分析输出,发现完全一致。 样例输出截图如下:

由此可见,在vim出问题的台式机上, autocmd是在正确工作的。 于是,问题的所在必然是autocmd产生的记录没有被保存下来。

203 - vim verbose输出分析,发现了关键文件.viminfo

$ vim -V /tmp/foo.c
chdir(/tmp)
fchdir() to previous dir
...<snip>...
Searching for "/usr/share/vim/vimfiles/after/pack/*/start/*"
Searching for "/home/huanli/.vim/after/pack/*/start/*"
not found in 'packpath': "pack/*/start/*"
Reading viminfo file "/home/huanli/.viminfo" info oldfiles
Press ENTER or type command to continue

因此,我们可以大胆地做如下猜测,autocmd在正常工作,上次的光标位置有被autocmd记录下来,但是因为未知的原因没有保存到.viminfo中去。

204 - 查看.viminfo的权限,发现owner:group是root:root(而不是huanli:huanli),于是找到了vim异常的root cause。

$ ls -l ~/.viminfo
-rw------- root root Jan : /home/huanli/.viminfo

显然,普通用户huanli没有权限修改.viminfo文件,所以autocmd记忆结果无法保存下来给下一次vim打开文件后使用。 解决的方法异常简单,

$ sudo chown huanli:huanli /home/huanli/.viminfo

但是,引起这次vim异常的罪魁祸首是什么呢?也就是说,为什么使用root做vim编辑的时候,.viminfo文件保存在/home/huanli目录下面而不是/root?

205 - 查看使用root用户时的环境变量HOME,发现HOME=/home/huanli而不是/root

root@DELL380:~# env | grep HOME
~HOME=/root
HOME=/home/huanli

好了,原来是HOME未被设置成/root, 虽然~HOME为/root。 于是,罪魁祸首找到了,那就是一个叫做so的alias。

huanli@DELL380:~$ alias | grep '~HOME'
alias so='sudo -s ~HOME=/root'

这跟我平常的使用习惯有关,因为我在普通用户(huanli)设置了彩色的PS1和alias so, 通过so就可以很容易地切换到root用户而且保持彩色的PS1。

原来如此,这就是典型的蝴蝶效应,一个由'sudo -s ~HOME=/root'引发的vim使用异常!!

3. 总结陈词

整个trouble shooting的过程其实是充满了乐趣的,虽然比较艰辛。我在结束202步的时候差一点就放弃了,因为要哄娃睡觉。后来冷静地想了想,估计跟存储有关(在Inspur干过存储还是有用的)。于是通过最为关键的'vim -V'找到了root cause(P.S. verbose输出对于软件调试简直就是必杀技)。软件调试和故障诊断其实跟医生看病差不多,基本思想是采用排除法。当然,也需要大胆地猜测,靠谱地猜测,经验越丰富,猜得越快,猜得越靠谱。医生越老越值钱,理论上说,程序员也是啊,呵呵。。。

It's not enough to be the best at what you do; you must be perceived as the only one who does what you do. | 在你那一行成为最强的还不够,你必须被视为你那一行的唯一。 

蝴蝶效应--由'sudo -s ...'引发的vim autocmd使用异常的更多相关文章

  1. 引发了未经处理的异常:读取访问权限冲突。 _First 是 nullptr。

    1.问题:程序崩溃出现错误 引发了未经处理的异常:读取访问权限冲突. _First 是 nullptr. string strreponse=0: 定义这条语句,字符串初始化错误. 自己开发了一个股票 ...

  2. 关于foreach中对集合执行Add或者Remove操作引发枚举值被修改异常

    方法传入集合List<string> ids; 执行操作后再次循环引发异常 foreach (string id in ids) { ids.Add("a"); } 更 ...

  3. 一个低级错误引发Netty编码解码中文异常

    前言 最近在调研Netty的使用,在编写编码解码模块的时候遇到了一个中文字符串编码和解码异常的情况,后来发现是笔者犯了个低级错误.这里做一个小小的回顾. 错误重现 在设计Netty的自定义协议的时候, ...

  4. 学习vim命令:“:w !sudo tee %”

    学习vim命令:“:w !sudo tee %” Original URL:http://www.haw-haw.org/node/1501 原文来自于commandlinefu 原文是这样解释这个命 ...

  5. Debian下安装vim

    问题描述:安装完系统以后,刚要打算开始写程序,发现,vim还没有装,用su -切换到root后 直接运行apt-get install vim,提示插入disc源,然后回车,陷入无法解决的状态. 上网 ...

  6. Ubuntu14 搭载vim环境查看源码

    首先是下载完整的vim74,然后编译安装.遗憾的是当编译时,没有开启图形界面. 在安装新版本的Vim之前,你需要卸载原来安装的老版本Vim,依次在终端下执行下列命令: sudo apt-get rem ...

  7. Fedora 19 vim c语言开发环境

    1. Fedora 19 居然没有自带 gcc 和 g++: sudo yum -y install gcc gcc-c++ 2. 安装 vim 和 cvim 插件: sudo yum -y vim ...

  8. vim/Gvim配置

    " Sections:" -> General" -> VIM user interface" -> Colors and Fonts&quo ...

  9. vim配置-程序员【转】

    Ubuntu11.10的vim升级后,版本为vi Improved 7.3.154功能很强大了.不过,程序员要根据自己的习惯配置好vimrc文件,是vim更加得心应手. 注:一般用户在自己的当前目录下 ...

随机推荐

  1. hdu 5018

    http://acm.hdu.edu.cn/showproblem.php?pid=5018 任意给你三个数,让你判断第三个数是否在以前两个数为开头组成的Fibonacci 数列中. 直接暴力 #in ...

  2. 使用WebService与Oracle EBS进行集成

    http://www.cnblogs.com/isline/archive/2010/04/15/1712428.html 一.概述 OracleEBS是Oracle公司的ERP产品,这个产品非常庞大 ...

  3. EJB、RMI、XMLRPC、Hessian、Thrift 、Protobuf

    Java中实现分布式的方式有:EJB.RMI.XMLRPC.Web Service.Hessian.Thrift .Protobuf.NIO(Netty.Mina) EJB 优势:可扩展性好,安全性强 ...

  4. 使用Java web工程建立Maven Web Module工程

    1. 前言 之前有一篇关于搭建S2SH的文章中提到建立Maven Web Module工程,有人反馈说这个方面不会.那还是唠叨一下,写篇文章说明一下吧. 建立Maven Web Module的方式有多 ...

  5. 开源WebGIS实施方案(六):空间数据(PostGIS)与GeoServer服务迁移

    研发环境的变更,或者研发完成进行项目现场实施.运维的时候,经常就会面临数据及服务的迁移,这其中就包含空间数据以及GeoServer服务的迁移工作. 这里需要提醒的是:如果采用的是类似的开源WebGIS ...

  6. 基于EasyUi的datagrid合并单元格JS写法

    $('#dg').datagrid({ width: 'auto', height: 'auto', scrollbarSize: , queryParams: {}, url: 'kkkk', co ...

  7. CSS3 & 页面布局

    相关链接 视频链接: CSS3 & 页面布局 CSS3与页面布局学习总结(一) CSS3与页面布局学习总结(二) CSS3与页面布局学习总结(三) CSS3与页面布局学习总结(四) CSS3与 ...

  8. 使用node_redis进行redis数据库crud操作

    正在学习使用pomelo开发游戏服务器,碰到node.js操作redis,记录一下 假设应用场景是操作一个用户表的数据 引入node_redis库,创建客户端 var redis = require( ...

  9. [Uliweb]-URL映射

    URL映射¶ Uliweb使用Werkzeug的Routing来进行URL的处理.当你使用manage.py的makeapp命令生成一个新 的App时,它会自动生成views.py文件,其中会自动从u ...

  10. php 删除二维数组中某个key值

    /** * 根据key删除数组中指定元素 * @param array $arr 数组 * @param string/int $key 键(key) * @return array */ priva ...