蝴蝶效應--由'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 oldfilesPress 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輸出對於軟件調試簡直就是必殺技)。軟件調試和故障診斷其實跟醫生看病差不多,基本思想是采用排除法。當然,也需要大膽地猜測,靠譜地猜測,經驗越豐富,猜得越快,猜得越靠譜。醫生越老越值錢,理論上說,程序員也是啊,呵呵。。。
蝴蝶效應--由'sudo -s ...'引發的vim autocmd使用異常