• 蝴蝶效应--由'sudo -s ...'引发的vim autocmd使用异常


    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("'"") > 0 && 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------- 1 root root 6533 Jan 1 23:35 /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. | 在你那一行成为最强的还不够,你必须被视为你那一行的唯一。 
  • 相关阅读:
    从员工到总监,我的7个经验心得(转)
    对上司不满,说还是不说
    老子智慧-大道甚夷
    实际操作中命令 su 与 sudo 的区别(转)
    杨氏矩阵查找元素位置Java实现
    Java实现 蓝桥杯 算法提高 周期字串
    Java实现 蓝桥杯 算法提高 周期字串
    Java实现 蓝桥杯 算法提高 学霸的迷宫
    Java实现 蓝桥杯 算法训练 最大最小公倍数
    Java实现 蓝桥杯 算法训练 最大最小公倍数
  • 原文地址:https://www.cnblogs.com/idorax/p/8384055.html
Copyright © 2020-2023  润新知