如何在Linux VPS上使用Vim
一个围绕真实服务器管理任务构建的Vim实用教程。学习模式、导航、编辑、搜索替换、分屏、.vimrc配置,以及通过SSH编辑Nginx、SSH和Docker Compose文件的工作流程。
Vim是大多数Linux服务器上的默认文本编辑器。当你通过SSH连接到VPS编辑Nginx配置、更改SSH端口或调整Docker Compose文件时,Vim就是你的工具。本教程通过真实的服务器管理任务来教授Vim,而不是抽象的示例。
你将学习Vim模式的工作原理、如何高效导航和编辑文件、如何搜索和替换文本、如何使用分屏和缓冲区处理多个文件,以及如何设置一个让服务器工作更快的.vimrc。
前提条件: 一台Linux VPS(Debian或Ubuntu),具有SSH访问权限。基本的终端操作能力(执行命令、切换目录)。
如何在Ubuntu或Debian上安装Vim?
大多数Debian和Ubuntu服务器预装了vim-tiny,这是一个精简版本,缺少语法高亮、撤销历史和插件支持。安装完整版本以获得本教程涵盖的所有功能。
sudo apt update && sudo apt install vim -y
验证安装:
vim --version | head -1
Debian 12(Bookworm)上的预期输出:
VIM - Vi IMproved 9.0 (2022 Jun 28, compiled Nov 15 2023 17:28:07)
在Ubuntu 24.04 LTS上,你会看到Vim 9.1。具体的补丁版本因发行版而异,但本教程中的所有功能在Vim 8.2及更高版本上都能正常工作。
Neovim怎么样? Neovim是Vim的一个分支,采用基于Lua的配置系统和内置LSP支持。本教程中的所有内容都适用于Neovim,除了.vimrc路径(Neovim使用~/.config/nvim/init.vim)。如果你更喜欢Neovim,可以用sudo apt install neovim安装。
启动内置教程
Vim自带一个大约需要30分钟的交互式教程。如果你从未使用过Vim,请在继续阅读前运行它:
vimtutor
这会打开一个练习文件,让你在实践中学习。它涵盖了移动和编辑的基础知识。本文的其余部分会更深入,并添加vimtutor未涵盖的服务器特定工作流程。
Vim模式是什么,如何工作?
Vim有四种主要模式。普通模式(Normal mode)是默认模式,用于导航和执行命令。插入模式(Insert mode)用于输入文本,按i进入。可视模式(Visual mode)用于选择文本,按v进入。命令行模式(Command-line mode)用于执行保存和退出等命令,按:进入。按Esc从任何其他模式返回普通模式。
这与nano等编辑器不同,在那些编辑器中你可以立即输入。在Vim中,普通模式下的按键是命令而不是字符。这叫做模态编辑。
| 模式 | 进入方式 | 用途 | 返回普通模式 |
|---|---|---|---|
| 普通 | Esc(或打开文件) |
导航、删除、复制、粘贴、执行命令 | 已在普通模式 |
| 插入 | i、a、o、I、A、O |
输入和编辑文本 | Esc |
| 可视 | v(字符)、V(行)、Ctrl+v(块) |
选择文本进行操作 | Esc |
| 命令行 | : |
执行ex命令(保存、退出、搜索、替换) | Enter或Esc |
模式指示器显示在屏幕左下角。当你看到-- INSERT --时,你处于插入模式。什么都没显示时,你处于普通模式。
如果你感到卡住了: 按两三次Esc。无论当前状态如何,这总能让你回到普通模式。
如何在Vim中导航文件?
Vim中的导航在普通模式下进行。基本的移动键是h(左)、j(下)、k(上)和l(右)。方向键也能用,但hjkl能让你的手指保持在主键位上,形成肌肉记忆后速度更快。
字符和行移动
| 按键 | 操作 |
|---|---|
h |
向左移动一个字符 |
j |
向下移动一行 |
k |
向上移动一行 |
l |
向右移动一个字符 |
0 |
跳到行首 |
$ |
跳到行尾 |
^ |
跳到第一个非空字符 |
单词移动
| 按键 | 操作 |
|---|---|
w |
跳到下一个单词开头 |
b |
跳回上一个单词开头 |
e |
跳到当前单词末尾 |
W |
跳到下一个WORD(以空格分隔) |
B |
跳回上一个WORD |
文件内移动
| 按键 | 操作 |
|---|---|
gg |
跳到文件第一行 |
G |
跳到文件最后一行 |
42G或:42 |
跳到第42行 |
Ctrl+d |
向下滚动半页 |
Ctrl+u |
向上滚动半页 |
Ctrl+f |
向下滚动一整页 |
Ctrl+b |
向上滚动一整页 |
% |
跳到匹配的括号((、{、[) |
搜索导航
按/向前搜索,输入搜索词后按Enter。按n跳到下一个匹配项,按N跳到上一个匹配项。按?向后搜索。
示例:你正在编辑/etc/nginx/nginx.conf,需要找到worker_connections指令:
/worker_connections
Vim跳到第一个匹配项。按n在文件中循环浏览所有匹配项。
如何在Vim中编辑文本?
Vim中的编辑遵循一个模式:操作符+动作。操作符指定做什么(删除、更改、复制)。动作指定作用于什么文本(单词、行、段落)。这种可组合性是Vim在你掌握几个基本构建块后变得快速的原因。
进入插入模式
| 按键 | 操作 |
|---|---|
i |
在光标前插入 |
a |
在光标后追加 |
I |
在行首插入 |
A |
在行尾追加 |
o |
在下方新建一行并进入插入模式 |
O |
在上方新建一行并进入插入模式 |
删除、更改、复制和粘贴
| 命令 | 操作 |
|---|---|
x |
删除光标下的字符 |
dd |
删除整行 |
dw |
从光标删除到下一个单词开头 |
d$或D |
从光标删除到行尾 |
cc |
更改整行(删除并进入插入模式) |
cw |
更改单词(删除单词并进入插入模式) |
ci" |
更改引号内的内容(删除"之间的文本并进入插入模式) |
yy |
复制(yank)整行 |
yw |
复制单词 |
p |
在光标后粘贴(put) |
P |
在光标前粘贴 |
撤销和重做
| 按键 | 操作 |
|---|---|
u |
撤销上一次更改 |
Ctrl+r |
重做(撤销撤销) |
. |
重复上一次更改 |
.(点)命令是Vim最有用的功能之一。它重复你上一次的操作。用cw更改一个单词,输入替换内容,按Esc。然后移到另一个单词,按.执行相同的更改。
与服务器相关的编辑示例
从Nginx配置中删除一条指令:
将光标放在access_log /var/log/nginx/access.log;这一行上,按dd删除整行。
更改引号中的端口号:
将光标放在Docker Compose文件中"8080"内的任意位置,按ci"。这会删除8080并让你进入插入模式。输入3000,按Esc。
从指令中删除两个单词:
按d2w从光标位置删除接下来的两个单词。Vim命令在动作前接受数字:3dd删除三行,5j向下移动五行。
如何在Vim中搜索和替换文本?
使用:s(substitute)替换文本。基本语法是:s/旧文本/新文本/标志。此命令默认作用于当前行。使用:%s将其应用于整个文件。
替换模式
| 命令 | 操作 |
|---|---|
:s/foo/bar/ |
在当前行替换第一个foo为bar |
:s/foo/bar/g |
在当前行替换所有foo为bar |
:%s/foo/bar/g |
在整个文件替换所有foo为bar |
:%s/foo/bar/gc |
替换所有并逐个确认(y/n) |
:5,10s/foo/bar/g |
在第5到10行替换所有 |
实际示例
将Nginx监听端口从80改为443:
:%s/listen 80;/listen 443 ssl;/g
在sshd_config中注释一行:
移到该行,按I在开头插入,输入#,按Esc。
注释多行: 用V(可视行模式)选择行,用j向下扩展选区,然后输入:s/^/#/并按Enter。这会在每个选中行前添加#。
替换Docker镜像标签:
:%s/nginx:1.24/nginx:1.27/g
Vim替换中的正则表达式基础
Vim使用自己的正则表达式语法。以下是在服务器配置中常用的几个模式:
| 模式 | 匹配 |
|---|---|
^ |
行首 |
$ |
行尾 |
. |
任意单个字符 |
\d |
一个数字(0-9) |
.* |
任意字符(贪婪) |
\s |
空白字符 |
要匹配字面上的点(如IP地址中的点),需要转义::%s/192\.168\.1\.1/10.0.0.1/g。
如何在Vim中使用分屏和缓冲区编辑多个文件?
Vim可以使用缓冲区、分屏窗口和标签页在单个会话中打开多个文件。当你需要在编辑时交叉引用文件时,这很有用,比如在编辑特定server块时查看nginx.conf。
缓冲区
缓冲区是加载到内存中的文件。你可以同时打开多个缓冲区并在它们之间切换。
| 命令 | 操作 |
|---|---|
:e /etc/nginx/sites-available/default |
在新缓冲区中打开文件 |
:bn |
切换到下一个缓冲区 |
:bp |
切换到上一个缓冲区 |
:ls |
列出所有打开的缓冲区 |
:b2 |
切换到第2号缓冲区 |
:bd |
关闭当前缓冲区 |
分屏窗口
分屏让你在同一个终端中并排查看两个文件。
| 命令 | 操作 |
|---|---|
:sp /文件/路径 |
水平分屏(上/下) |
:vs /文件/路径 |
垂直分屏(左/右) |
Ctrl+w h/j/k/l |
在分屏间移动(左/下/上/右) |
Ctrl+w = |
使所有分屏大小相等 |
Ctrl+w q |
关闭当前分屏 |
工作流程示例:编辑Docker Compose文件的同时查看.env文件:
:e docker-compose.yml
:vs .env
现在你有两个面板。使用Ctrl+w l和Ctrl+w h在它们之间切换。
标签页
标签页是窗口的集合。大多数人认为分屏对于服务器工作来说已经足够,但标签页也可以使用:
| 命令 | 操作 |
|---|---|
:tabnew /文件/路径 |
在新标签页中打开文件 |
gt |
切换到下一个标签页 |
gT |
切换到上一个标签页 |
:tabclose |
关闭当前标签页 |
如何使用.vimrc文件自定义Vim?
主目录中的.vimrc文件控制Vim的行为。没有它,Vim会以几乎兼容Vi的模式运行,缺少许多功能。一个针对服务器工作调优的.vimrc能让编辑配置文件更快。
创建或编辑你的.vimrc:
vim ~/.vimrc
添加以下设置。每行都有注释说明其作用:
" Disable Vi compatibility mode (enable all Vim features)
set nocompatible
" Use UTF-8 encoding (required for special characters in listchars on minimal server images)
set encoding=utf-8
" Show line numbers (essential for config files with error messages referencing line numbers)
set number
" Show relative line numbers (makes jumping N lines easy: 5j, 12k)
set relativenumber
" Enable syntax highlighting
syntax on
" Use spaces instead of tabs (most config files expect spaces)
set expandtab
" Set tab width to 2 spaces (common for YAML, Nginx configs)
set tabstop=2
set shiftwidth=2
set softtabstop=2
" Highlight search results as you type
set incsearch
set hlsearch
" Case-insensitive search unless uppercase is used
set ignorecase
set smartcase
" Show matching brackets
set showmatch
" Always show the status line (shows filename and position)
set laststatus=2
" Enable mouse support (useful in modern terminals)
set mouse=a
" Show current mode in status line
set showmode
" Set pastetoggle to F2 (toggle paste mode for clean pasting over SSH)
set pastetoggle=<F2>
" Disable swap files (avoids .swp clutter on servers)
set noswapfile
" Enable filetype detection (loads correct indentation for yaml, json, etc.)
filetype plugin indent on
" Highlight the current line
set cursorline
" Show whitespace characters (catch trailing spaces and mixed indentation)
set list
set listchars=tab:»·,trail:·
用:wq保存并退出。设置在下次打开Vim时生效。
不重启Vim重新加载.vimrc:
:source ~/.vimrc
SSH会话的粘贴模式
当你通过SSH将本地剪贴板的文本粘贴到Vim中时,自动缩进可能会产生阶梯效果,每行都比上一行更靠右。这是因为Vim把粘贴的文本当作键盘输入,并对每行应用缩进规则。
粘贴前开启粘贴模式:
- 按
F2(如果你按上面的方法设置了pastetoggle)或输入:set paste - 按
i进入插入模式 - 粘贴文本(终端中按Ctrl+Shift+V或右键)
- 再次按
F2或输入:set nopaste
Vim 8.2+的现代终端支持括号粘贴模式(bracketed paste mode),会自动处理这个问题。如果你使用较新的终端模拟器(kitty、Alacritty、WezTerm、较新的GNOME Terminal),可能不需要手动切换粘贴模式。
如何用vim-plug添加插件?
vim-plug是一个轻量级插件管理器,可以并行安装插件。它只需要下载一个文件并在.vimrc中添加几行配置。
安装vim-plug
curl -fLo ~/.vim/autoload/plug.vim --create-dirs \
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
验证文件是否存在:
ls -la ~/.vim/autoload/plug.vim
你应该能看到该文件,所有者是你的用户。
在.vimrc中配置插件
在~/.vimrc的顶部、设置之前添加插件块:
call plug#begin('~/.vim/plugged')
" File explorer sidebar
Plug 'preservim/nerdtree'
" Fuzzy file finder
Plug 'junegunn/fzf', { 'do': { -> fzf#install() } }
Plug 'junegunn/fzf.vim'
" Git status indicators in the gutter
Plug 'airblade/vim-gitgutter'
call plug#end()
保存文件,然后安装插件:
:source ~/.vimrc
:PlugInstall
vim-plug会并行下载每个插件。安装后,你可以用:NERDTree打开NERDTree,用:Files模糊查找文件,在边栏看到git diff标记。
在服务器上保持精简。 插件会增加启动时间。在偶尔编辑配置文件的VPS上,三到五个插件就够了。更重的配置留给你的本地开发机器。
如何通过SSH用Vim编辑服务器配置文件?
本节介绍管理VPS时会反复使用的工作流程。每个示例都使用真实文件并展示确切步骤。
使用sudoedit而不是sudo vim
编辑root所有的文件(如/etc/nginx/nginx.conf或/etc/ssh/sshd_config)时,使用sudoedit而不是sudo vim。
sudoedit /etc/nginx/nginx.conf
sudoedit将文件复制到临时位置,用你的用户的Vim打开它(包括你的.vimrc设置和插件),然后在你保存退出时以root权限将其复制回去。这比sudo vim更安全,原因有两个:
sudo vim以root身份运行Vim。任何Vim命令如:!bash都会启动root shell。在多用户服务器上,这是一个权限提升风险。sudoedit保留你的用户环境。你保有语法高亮、行号和快捷键。
编辑Nginx server块
打开默认站点配置:
sudoedit /etc/nginx/sites-available/default
输入/server_name并按Enter找到server_name指令。Vim跳到匹配处。按cw更改指令后的单词,输入你的域名,按Esc。
保存后验证Nginx配置语法:
sudo nginx -t
预期输出:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
然后重新加载:
sudo systemctl reload nginx
在sshd_config中更改SSH端口
sudoedit /etc/ssh/sshd_config
搜索端口指令:
/^#\?Port
这个正则表达式同时匹配Port和#Port(被注释的)。如果该行被注释,按0跳到行首,按x删除#,然后按f加空格跳到端口号前的空格处。按cw,输入新端口号(例如2222),按Esc。
验证配置:
sudo sshd -t
没有输出表示语法有效。重启服务:
sudo systemctl restart sshd
断开连接前,在新端口上打开第二个SSH会话,验证你仍然可以连接。更改端口后不测试就丢失SSH访问权限是一个常见错误。
编辑Docker Compose文件
vim ~/myapp/docker-compose.yml
YAML文件对缩进敏感。之前设置的.vimrc(2空格缩进、expandtab)能正确处理这一点。如果你在YAML文件中看到制表符,转换它们:
:%s/\t/ /g
这会将所有制表符替换为两个空格。保存并验证文件:
docker compose config --quiet
没有输出表示YAML有效。如果有语法错误,Docker Compose会打印行号。用vim +42 docker-compose.yml直接跳到Vim中的那一行(42是错误行号)。
编辑systemd unit文件
sudoedit /etc/systemd/system/myapp.service
保存systemd unit的更改后,重新加载daemon:
sudo systemctl daemon-reload
然后重启服务并验证:
sudo systemctl restart myapp
sudo systemctl status myapp
检查状态输出中的Active:行。它应该显示active (running)。如果显示failed,查看日志:
journalctl -u myapp -n 20 --no-pager
Vim速查表
第一天就需要的十个命令:
| 命令 | 操作 |
|---|---|
i |
进入插入模式 |
Esc |
返回普通模式 |
:wq |
保存并退出 |
:q! |
不保存退出 |
dd |
删除行 |
u |
撤销 |
/text |
向前搜索 |
:%s/old/new/g |
替换文件中的所有匹配 |
:sp file |
分屏 |
F2 |
切换粘贴模式 |
完整参考(包括导航、编辑、可视模式、缓冲区、分屏、正则表达式和服务器工作流快捷操作),请查看我们的Vim速查表。
出了问题?
Vim打开了但我无法输入。 你处于普通模式。按i进入插入模式。
我看到-- INSERT --但按键行为异常。 你可能不小心按了Ctrl+s,这会冻结终端输出。按Ctrl+q解冻。
我粘贴的文本有阶梯形缩进。 粘贴前用F2或:set paste开启粘贴模式。粘贴后记得关闭:再次按F2或:set nopaste。
Vim提示"E45: 'readonly' option is set." 文件是只读的。用:q退出,然后用sudoedit /文件/路径重新打开。
我犯了错误并且已经保存了。 如果是系统配置文件,Vim可能留下了备份。在同一目录中查找filename~。如果你在.vimrc中设置了set undofile和set undodir=~/.vim/undodir(先用mkdir -p ~/.vim/undodir创建目录),也可以在重新打开后撤销。
交换文件警告:".file.swp"已存在。 之前的Vim会话崩溃或仍在打开。如果没有其他会话在编辑该文件,选择(D)elete删除交换文件。如果你在.vimrc中禁用了交换文件(set noswapfile),这种情况不会出现。
下一步: 将Vim与终端复用器搭配使用,让你的编辑会话在断连后仍然存在。参见我们的tmux指南或GNU Screen指南。本文中的Nginx配置示例,可在Nginx管理完整指南中查看。
版权所有 2026 Virtua.Cloud。保留所有权利。 本内容为 Virtua.Cloud 团队原创作品。 未经书面许可,禁止复制、转载或再分发。