如果你曾经在Ubuntu终端里敲过vi,然后发现自己进去了出不来,满脑子只有“退出vi编辑模式怎么弄”——恭喜,你不是一个人。vim/vi在Ubuntu下一直是绕不开的存在,无论你是要改个服务器配置、跑crontab -e还是用visudo提权编辑文件,系统都会把你丢进vi的界面里。这篇东西不是官方文档翻译,是我长期在Ubuntu下折腾vim攒下的实操经验,从安装、模式理解、常用命令、配置文件到swap文件排查,一步步拆开讲清楚,建议收藏后跟着敲一遍。
1. 为什么在Ubuntu上绕不开vim/vi?先从“默认编辑器”说起
1.1 Ubuntu自带vi,而vim是它的增强版
Ubuntu和大多数Linux发行版一样,默认安装了一个精简版vi,很多人以为这就是vim,其实不完全对。vim全称是Vi IMproved,是vi的增强替代品,增加了语法高亮、多级撤销、可视模式选择、插件体系等大量功能。Ubuntu默认环境里,你直接敲vi,往往打开的是vim.tiny或完整的vim,取决于你是否安装了vim包。区分方法很简单:在终端输入vi --version,如果看到的是VIM - Vi IMproved那说明已经有完整vim;如果提示命令不存在,或者只有简单报错,那就需要自己装。
1.2 什么时候你被迫用vi:crontab、visudo、无图形界面的服务器
很多新手会问:既然Ubuntu有图形界面,为什么还要学vim?因为系统关键命令的默认编辑器就是vi。典型场景包括:用sudo crontab -e编辑定时任务,用sudo visudo修改sudo权限配置,用systemctl --user edit修改服务参数,以及在没有桌面环境的服务器上查看日志和改配置文件。这些场景不是“选不选vim”的问题,而是“不会vim就卡死在终端里”的问题。
我针对这点多提一句:你可以通过sudo update-alternatives --config editor把系统默认编辑器换成nano,但这只是回避问题。服务器上不一定装了nano,而且很多运维老手默认就是vim习惯,你至少要把“打开、编辑、保存、退出”这四步练熟,才能保证在任何机器上都不慌。
1.3 在Ubuntu上安装vim:软件源、版本选择与验证
如果你的系统里确实没有完整vim,安装很简单:
sudo apt update sudo apt install vim -y装完可以验证版本:
vim --version这条命令会输出一大堆编译特性,不用全看懂,重点看+python3、+clipboard这几个标志。带+说明编译时包含了该特性,+clipboard决定vim能否使用系统剪贴板,这个在图形界面下挺重要。如果想装带图形界面的版本,比如vim-gtk3,可以用:
sudo apt install vim-gtk3 -y它提供gvim命令,界面是图形窗口,但命令行vim的使用逻辑完全没有差别。如果你在编译安装vim时遇到GUI库相关问题,比如提示缺少libgtk-3-dev、libgnome2-dev之类的依赖,先跑一遍sudo apt build-dep vim把编译依赖补齐,再执行./configure --with-features=huge --enable-python3interp --with-python3-command=python3配置编译参数,最后make和sudo make install。
2. 理解vim的工作模式:这是正确使用的前提
2.1 四种模式:正常、插入、可视、命令行
vim和普通编辑器的最大区别就是“模式”。日常用的有四种:
- 正常模式:启动vim后默认所在模式,此时键盘上的按键不是输入字符,而是执行命令。
j下移、k上移、dd删除一行、yy复制一行。 - 插入模式:按
i进入,此时键盘才真正输入文字。按Esc返回正常模式。 - 可视模式:按
v进入,用方向键选择文本块,选中后按d删除、按y复制。V是行选择,Ctrl+v是列选择。 - 命令行模式:正常模式下按
:进入,底部出现冒号输入框,执行保存、退出、替换等命令。按/也可进入,用于向下搜索。
理解模式的关键在于:你敲什么键、得到什么结果,完全取决于当前模式。新手崩溃的根源,就是把正常模式当成输入状态,噼里啪啦敲了一堆字母,屏幕上没出字,反而文件被改得乱七八糟。
2.2 模式切换逻辑:新手最容易“卡住”的真正原因
我见过太多人描述自己“卡在vi里”,其实不是真的锁死,而是不知道怎么从当前模式回到正常模式,或者不知道当前处于哪个模式。
我的建议是永远记住一个锚点:Esc是返回正常模式的万能键。不管你在插入模式还是命令行模式,先按几下Esc,确保回到正常模式,再做下一步操作。为了减少误判,可以在~/.vimrc里设置显示当前模式:
set showmode这会在底部显示-- INSERT --之类的提示。还有更直观的做法是配置状态栏显示模式,不过入门阶段set showmode已经够用。
还有一个隐藏较深的问题:有些终端环境会拦截功能键,或者按键序列被终端模拟器吃掉,导致按Esc没反应,或者方向键变成A、B、C、D字母。这种情况我在WSL的早期版本里遇见过,根源是终端设置和vim配置冲突。解决办法是把光标键映射也配进vimrc,或者改用Ctrl+[代替Esc——Ctrl+[是Esc的等效输入,任何终端都不会拦截它。
2.3 “退出vi编辑模式”到底怎么退:写给搜这个词的人
“退出vi编辑模式”是高热搜词,说明大量用户卡在这一步。我把退出场景完整拆一遍,按情况对号入座:
- 刚打开文件,什么都没改,想退出:正常模式下输入
:q再回车。 - 改了内容但想放弃保存:输入
:q!再回车,感叹号表示强制退出且不保存。 - 改了内容且要保存并退出:输入
:wq再回车,w是写入,q是退出。 - 只想保存但继续编辑:输入
:w回车。 - 保存并退出的快捷方式:正常模式下按
ZZ(大写Z,连按两次)等价于:wq。如果不保存直接退出,可按ZQ,等价于:q!。
如果你不确定自己改没改过文件,又不想冒险丢内容,可以先:w保存,再:q退出。或者按下Ctrl+Z把vim放到后台挂起,回到shell后用fg再切回去——不过这属于临时逃生方案,不建议依赖。
3. 高频命令速查:把最常用操作变成肌肉记忆
3.1 光标移动与文件导航
vim之所以高效,是因为手不用离开键盘主区域就能完成大部分移动和编辑。入门先记这些移动命令:
| 命令 | 作用 |
|---|---|
h/j/k/l | 左 / 下 / 上 / 右移动 |
w | 跳到下一个单词开头 |
b | 跳到上一个单词开头 |
0 | 跳到行首 |
^ | 跳到行首第一个非空字符 |
$ | 跳到行尾 |
gg | 跳到文件第一行 |
G | 跳到文件最后一行 |
Ctrl+f | 向下翻一页 |
Ctrl+b | 向上翻一页 |
这些命令都能加数字前缀,比如5w表示向后移动5个单词,3j表示向下移动3行。这个“数字+命令”的组合是vim操作的精髓,能让你从一次移动一行,升级为一次跳转到目标位置。
文件导航还有个高阶技巧:用Ctrl+o和Ctrl+i在跳转历史中来回移动,类似浏览器的前进后退。这个功能在编辑大文件时非常好用,比如你从第500行跳到第50行改完,按一次Ctrl+o就回到之前的位置。
3.2 编辑:删除、复制、粘贴、撤销、重复
编辑命令也遵循“动词+对象”的组合逻辑。最常用的动词是d(删除)、y(复制)和c(修改,即删除并进入插入模式),对象可以是w(单词)、$(到行尾)、0(到行首)、j(向下行)等。
实际场景举例:
dw:删除从光标到单词结尾;dd:删除整行,5dd删除5行;d$:删除从光标到行尾;yy:复制整行,3yy复制3行;p:在光标后粘贴,P在光标前粘贴;u:撤销上一次修改,可以和Ctrl+r(重做)搭配使用;.:重复上一次修改命令,这个非常神,想让同样的操作再来一次就按它。
有几个细节值得单独强调。第一,vim的“删除”和“剪切”是一回事,dd删掉的内容可以用p粘贴回来,所以不用担心删错,删错了按u撤销即可。第二,插入模式下退格键删除的是已有文本,但如果vim配置了set backspace=indent,eol,start,退格键才能跨过自动缩进和行首位置删除内容,这个问题在Ubuntu上很常见,默认配置不同会导致退格键“失灵”的错觉。
第三,c命令是“改”,和d类似但结果不同:cw删除一个单词并进入插入模式,适合替换单词场景;cc删除整行并进入插入模式,适合重写一行。新手常在这里混淆,以为dd后会进入输入状态,其实d不会,c才会。
3.3 全文搜索与替换:配合set ft认识文件类型机制
搜索在正常模式下按/,输入关键词后回车,vim会高亮所有匹配项。n跳到下一个匹配,N跳到上一个匹配。搜完想取消高亮,搜索一个不存在的词,或者执行:nohlsearch。我通常会在vimrc里配置:
set hlsearch set incsearch前一个开启高亮,后一个开启增量搜索,即输入过程中实时定位匹配项,体验友好得多。
替换是另一个高频诉求。基础格式是:
:范围s/目标/替换/选项%s/foo/bar/g:全文替换所有foo为bar;%s/foo/bar/gc:全文替换,但每个匹配都会询问确认;3,10s/foo/bar/g:只替换第3行到第10行之间匹配的内容。
这里要说明一下set ft的作用。ft是filetype的缩写,:set ft=python可以让vim按Python语法规则高亮当前文件,:set ft=json则按JSON格式识别。搜索词里“vim: set ft”高频出现,是因为很多教程和配置文件开头会有vim: set ft=xxx:这样的模型行,它用于在文件内声明文件类型。虽然实际使用中大多数人靠vim自动识别文件类型就够了,但手动设置ft在处理未知扩展名或没有扩展名的脚本文件时非常有用。
想要vvim自动按扩展名识别文件类型并应用相应缩进和语法规则,在vimrc里加这三行:
filetype on filetype indent on filetype plugin on3.4 保存退出命令的区别:w、q、wq、q!、x、ZZ
我把这些命令对比整理成一个表格,方便直接对照记忆:
| 命令 | 行为 | 适用场景 |
|---|---|---|
:w | 保存文件,不退出 | 编辑中途存档 |
:q | 退出,未保存则提示 | 未做修改时退出 |
:wq | 保存并退出 | 改完收工 |
:q! | 放弃修改强制退出 | 改坏了,不想保存 |
:x | 有修改才保存并退出 | 和wq等价但有微妙差别 |
ZZ | 保存并退出 | 把:和回车都省了的快捷方式 |
ZQ | 不保存强制退出 | 等价于:q! |
:\x和:wq的区别在于修改时间戳:如果文件没有改动,:x不会更新文件的修改时间,而:wq总会写入。这在某些需要判断文件是否真的被改动的脚本场景中会有影响,日常使用感知不大。
还有一个我经常遇到的反直觉情况:以只读权限打开一个没有写权限的文件时,按:w会报错,但如果你用sudo启动的vim(比如sudo vim /etc/hosts),也许可以强制写入。在普通用户下临时需要保存系统文件,可以用:w !sudo tee %这个经典命令,它会通过shell调用sudo tee把缓冲区内容写回原文件。这个技巧第一次用的人会觉得像魔法,但它确实帮我在忘记用sudo打开文件时保住了修改。
4. 配置文件.vimrc:让vim成为一个趁手的编辑器
4.1 为什么一定要建自己的vimrc
裸奔状态的vim只能用“能用”来形容,跟“好用”差距很大。好在vim配置极其灵活,一个~/.vimrc就能改天换地。这个文件是vim启动时读取的配置脚本,纯文本格式,每行一个设置项或命令。Ubuntu下新建或编辑它用:
vim ~/.vimrc如果文件不存在会自动创建。下面这份配置我用了很久,兼顾了新手友好和日常效率,可以直接抄:
set number set relativenumber set showmode set showcmd set cursorline set autoindent set smartindent set tabstop=4 set shiftwidth=4 set expandtab set hlsearch set incsearch set ignorecase set smartcase set wildmenu set backspace=indent,eol,start set clipboard=unnamedplus syntax on filetype on filetype indent on filetype plugin on简明解释几个关键项:set number显示绝对行号,set relativenumber显示相对行号,方便你估算“往下5行”在哪个位置;set cursorline高亮当前行;set tabstop=4和set shiftwidth=4让Tab键和自动缩进都是4个空格宽度,set expandtab把Tab替换成空格,这是Python等对缩进敏感的语言的刚性需求;set ignorecase和set smartcase组合后,搜索时如果输入的是小写字母则不区分大小写,如果包含大写字母则区分大小写,很智能。
4.2 自动补全:从内置补全到插件方案
搜索词里“在vim中怎么自动补全”热度不低。vim本身就有内置补全能力,不用装插件也能临时救急。正常模式下插入状态,按Ctrl+n或Ctrl+p会弹出候选词列表,vim从当前文件、其他打开的文件以及include路径中收集关键词。虽然这个补全不智能,但足够应对写脚本时“记得大概拼写但记不全”的场景。
想要真正的代码补全,我推荐从插件管理开始。我给新手的最低成本方案是用vim-plug,安装:
curl -fLo ~/.vim/autoload/plug.vim --create-dirs \ https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim然后在vimrc里声明插件,比如配置coc.nvim作为补全引擎,它需要Node.js环境:
call plug#begin('~/.vim/plugged') Plug 'neoclide/coc.nvim', {'branch': 'release'} call plug#end()保存后执行:PlugInstall安装插件,再装对应语言的扩展,比如Python就是:CocInstall coc-python,这样写代码时才会有真正的语义补全、跳转定义和错误检查。
但我必须提醒一句:补全插件配置有陡峭学习曲线,如果只是偶尔改配置文件、写写Shell脚本,内置Ctrl+n补全完全够用。不要因为教程都在炫插件就一头扎进去,工具是服务任务的,先把手头的事做顺,再考虑进阶。
4.3 文件类型检测与特殊场景配置
vim对文件类型的识别遵守“先检测、后应用”的流程:它根据扩展名、文件路径和内容猜测文件类型,然后加载对应的缩进规则和语法文件。当猜测失败时,你才需要手动干预。常见干预手段有三种:
- 当前文件临时指定:
:set ft=nginx; - 永久为某类文件指定:在vimrc里写
autocmd BufNewFile,BufRead *.conf set ft=nginx; - 在文件内部写入模型行:文件末尾或开头加
# vim: set ft=python:,vim打开时自动执行这条设置。
模型行是个容易被忽视的小技巧。它特别适合那些没有扩展名、但内容其实是特定格式的脚本,例如由脚本动态生成的一些配置,或者Nginx的片段文件。我维护的运维脚本裸文件名通常是deploy.sh,有扩展名还好,但有些ansible模板文件没有固定扩展名,文件末尾加一行模型行,就能保证所有用vim打开的同事都得到正确的语法高亮。
5. 避坑实战:swap文件与vim崩溃恢复
5.1 swap文件的原理:为什么目录里突然多了隐藏文件
如果用过vim打开文件后又异常退出,下次打开时会看到一个警告:“Swap file .test.swp already exists!”很多新人以为文件坏了,其实这是vim的保护机制。
vim编辑文件时会生成同名隐藏swap文件,比如test.txt对应.test.txt.swp。这个文件持续记录你的修改内容。正常工作流程下,你保存退出后swap文件会被删除;但如果vim被强制终止(终端被关、系统断电、SSH掉线),swap文件就会残留。下次再打开原文件时,vim检测到swap存在,会警告可能上一次会话未正常结束,并提示你选择处理方式。
swap文件不是病毒,也不是文件损坏。它甚至可能是救命的稻草:如果你上一次崩溃前没保存,vim的-r恢复功能可以从swap文件里找回未保存内容。
5.2 处理swap文件的正确姿势:恢复、比对、清理
当vim弹出swap警告时,界面底部会有一排选项:
Open Read-Only:以只读方式打开原文件,不加载swap内容;Recover:用swap文件内容恢复,找回上次未保存的修改;Delete it:直接删除swap文件,相当于承认上次修改无效;Quit:退出;Abort:中止。
处理优先级应该是:先Recover或Open Read-Only检查内容,确认哪个版本是你想要的。如果恢复后确认没问题,再:wq保存退出,vim会清理swap文件。如果确认不要上次的修改,可以:q退出后手动删除残留swap:
rm .test.txt.swp我在Ubuntu下遇到过一种更隐蔽的情况:vim打开文件时提示swap文件存在,但编辑目录里根本看不到swap文件,因为文件名以.开头,普通ls不显示隐藏文件。这时候用ls -a才能看到。所以如果你打开文件总是报swap警告,先下意识跑一下ls -la。
5.3 WSL和虚拟机下的vim:剪贴板、方向键与中文输入
搜热搜词里能看到“wsl ubuntu写代码最推荐的字体接近macos的体验”,说明不少人是在Windows的WSL里用vim。WSL里的vim有几个常见怪问题,我集中说:
一是剪贴板不互通。默认vim里"+y和"+p无法访问Windows剪贴板,除非安装了支持clipboard特性的版本。检查vim --version里有没有+clipboard,如果没有,装vim-gtk3或用vim-gtk替代完整vim,一般能解决。二是终端对键盘序列的兼容问题,表现为方向键在插入模式输出ABCD,解决办法是set nocompatible,或确保set term正确,还可以在插入模式用Ctrl+p和Ctrl+n上下选择补全来减少对方向键的依赖。三是中文输入法焦点问题,在vim插入模式下呼出中文输入法,按Esc回到正常模式后,再按i进入插入模式,有时输入法状态会“拖住”,导致正常模式下的按键被输入法吃掉。这个目前没什么完美的命令行解决方案,只能是养成“进入vim后先把输入法切到英文模式”的习惯。
虚拟机里的vim问题通常集中在缩放和字体渲染上,建议在终端模拟器设置里调整字体为等宽字体,并开启“自动换行”或“剪贴板自动同步”。这一块跟vim本身关系不大,更多是终端配置的事,但体验影响很大。
6. Ubuntu下的编辑器选型:vim、nano与VSCode怎么选
6.1 服务器和终端环境:vim是下限,也是标配
如果在只有命令行的服务器上工作,编辑器只有两个选择:vim或nano。nano确实更易上手,底部一直显示操作快捷键,对新人极其友好。但nano在远程会话中的优势仅限于“简单修改”,一旦遇到大文件、高频重复编辑、复杂搜索替换,效率会明显低于vim。
所以我一直把vim称为“终端编辑器的下限”——你不需要成为vim高手,但至少要做到能打开、能看懂基本模式、能保存退出。这保证你到了任何一台Ubuntu服务器上,都能靠肌肉记忆完成最基本的配置修改,而不是被卡在原地。
6.2 图形界面和大工程:VSCode是另一种思路
热搜词里有“ubuntu安装vscode”,说明很多人最终会走向图形编辑器。我的态度很明确:工具是分场景的。在Ubuntu桌面环境下做中大型代码项目,VSCode的确比vim更舒服,图形化文件树、调试器、Git集成都是开箱即用。安装也方便,从官网下载deb包后sudo dpkg -i code_*.deb即可。
但即使在VSCode里,我依然建议你装上vim插件。这个插件提供vim按键绑定,让你在图形编辑器里也能用vim的移动和编辑命令,既保持了输入习惯,又享受了图形界面的便利。用上一周习惯了这种混合模式,再回到终端vim时不会生疏。
6.3 我的实际建议:先定一个“最简可用组合”
如果你刚开始学Ubuntu,别一上来就折腾vim的插件体系。我推荐的路线是:
- 用一周时间,把所有涉及
crontab -e、visudo、修改配置文件的场景都刻意用vim完成,只掌握i进入编辑、Esc退出、:wq保存退出、上下左右移动和dd删除一行,这足够应对90%的基础场景。 - 每天随手记下一个让自己工作变慢的瞬间,再去针对性学对应的vim命令。
- 等积累到二十个左右的常用命令后,再开始配置.vimrc,引入插件。
这个路线的好处是:每一步都是在真实需求驱动下学习,而不是对着命令表死记。我自己就是这样一步步从“完全不会vi”变成“终端里只用vim”的,过程大约持续了一个月,但之后就再也回不去nano了。