Vim 怎么退出?保存退出、不保存退出与 wq 退不出来怎么办
Vim 怎么退出:先按 Esc 回到普通模式,输入 :wq 回车是保存并退出,输入 :q! 回车是放弃修改直接退出。输入 :wq 后还停在 Vim 里,就看屏幕最底下一行:E37 是改动没保存,E45 是只读,E212 是没有写权限,E32 是文件还没有名字,按提示对应处理即可。
Vim 怎么退出,分两步:先按 Esc(不放心就多按两下),确认屏幕左下角没有 -- INSERT --、-- VISUAL -- 这类字样;然后输入冒号加命令,再按回车。:wq 是保存并退出,:q! 是不保存直接退出,文件没改过时 :q 就能退出。冒号必须是英文半角,命令区分大小写。按了回车仍然停在 Vim 里,说明 Vim 拒绝了这条命令,原因就写在屏幕最底下一行,下文按提示逐个给出处理办法。
保存退出和不保存退出:命令对照表
| 命令 | 怎么输入 | 文件有未保存的修改时 | 文件没有修改时 | 什么时候用 |
|---|---|---|---|---|
:wq |
Esc 后输入,回车 |
写入并退出 | 仍会写一次文件,修改时间被更新 | 最常用的保存退出 |
:x |
同上 | 写入并退出 | 不写文件,直接退出 | 只想保存真正有改动的文件 |
ZZ |
Esc 后连按两次大写 Z,不需要冒号和回车 |
同 :x |
同 :x |
:x 的快捷写法 |
:q |
Esc 后输入,回车 |
拒绝退出,报 E37 | 直接退出 | 只看不改的文件 |
:q! |
同上 | 丢弃全部修改,退出 | 直接退出 | 改乱了,不要了 |
ZQ |
Esc 后按大写 Z、大写 Q |
同 :q! |
同 :q! |
:q! 的快捷写法 |
:wq! |
同上 | 忽略只读标记强制写入,再退出;系统权限不允许时仍然失败 | 同左 | 以只读方式打开、确认自己有写权限时 |
:qa / :qa! |
同上 | :qa 遇到任何一个未保存的文件都会拒绝;:qa! 全部丢弃 |
全部退出 | 一次打开了多个文件或分了屏 |
:wqa / :xa |
同上 | 全部保存后退出 | 全部退出 | 同上 |
:cq |
同上 | 丢弃修改退出,并返回非零退出码 | 同左 | 让调用 Vim 的程序(如 git)放弃本次操作 |
三个容易混的地方:
:wq和:x只在“没改动”时有区别。:wq不管有没有改动都把文件重写一遍,文件的修改时间随之更新;:x和ZZ发现没改动就直接退出,不碰文件。多数时候无所谓,但依赖修改时间的程序会被惊动:按修改时间判断变化的同步、备份脚本会把它当成新文件,make会重新编译依赖它的目标,监听文件变化自动重载的服务也可能多重载一次。只是打开看看的配置,用:q或ZZ离开更干净。- 是大写
ZZ,不是小写。小写zz的作用是把当前行滚动到屏幕中间,按多少次都不会退出。同理,开着大写锁定输入:WQ,得到的是E492: Not an editor command: WQ。 !的意思是“我知道后果,照做”。它能越过 Vim 自己的保护,比如未保存提醒和只读标记,但越不过操作系统的文件权限:普通用户打开 root 的文件,:wq!照样写不进去。
先确认自己在哪个模式
输入 :wq 没效果,最常见的原因是当时不在普通模式。看屏幕左下角:
| 左下角显示 | 当前状态 | 这时输入 :wq 会怎样 | 怎么回到普通模式 |
|---|---|---|---|
-- INSERT -- |
插入模式 | :wq 三个字符被当成文字写进文件 |
按 Esc |
-- REPLACE -- |
替换模式,误按了 R,或在插入模式里按了键盘上的 Insert 键 |
输入的字符覆盖原有内容 | 按 Esc |
-- VISUAL --、-- VISUAL LINE --、-- VISUAL BLOCK -- |
可视模式(选中了文本) | 一按冒号,命令行自动变成 :'<,'>,接着输入 wq 回车,报 E140: Use ! to write partial buffer |
按 Esc |
recording @q 一类 |
正在录制宏,按了 q 再加一个字母 |
不影响退出,但之后的按键都会被录下来 | 再按一次 q 停止录制 |
显示过 Entering Ex mode,底部只剩一个冒号提示符 |
Ex 模式,误按了大写 Q(没有被配置文件改成别的功能时)或 gQ |
每输入一行就执行一行,不回到全屏界面 | 输入 visual 回车;直接输入 wq 回车也能保存退出 |
| 屏幕下方多出一个列着历史命令的小窗口 | 命令行窗口,把 :q 按成了 q: |
在这个小窗口里输入 :q 只会关掉小窗口 |
先 :q 关掉它,再 :q 退出 Vim |
| 没有任何字样 | 普通模式 | 正常执行 | — |
两种情况要特别小心:
- 在插入模式里打了
:wq。按Esc后先看清多出来的字符在哪,用x(删除光标所在的字符)删掉再保存。如果这一次插入只打了这三个字符,直接按u撤销最省事;但如果前面的正常修改也是在同一次插入里输入的,u会把它们一起撤掉。 - 可视模式下的 E140。这时实际执行的是
:'<,'>wq,意思是“只把选中的几行写进文件”。千万不要照提示加上!,那样文件就只剩选中的那几行了。按Esc退出可视模式,再重新输入:wq。
另外,中文输入法开着时,冒号会变成全角的“:”,Vim 不认这个字符,后面跟着的字母会被当成普通模式的命令执行,光标可能跳动,甚至开始录制宏。切回英文输入,按 Esc 后重新输入。
wq 退不出来:按底部提示逐个处理
| 底部提示 | 意思 | 处理 |
|---|---|---|
E37: No write since last change (add ! to override) |
用的是 :q,但文件改过还没保存 |
要保存用 :wq,不要就 :q! |
E162: No write since last change for buffer "a.conf" |
执行 :qa 时,另一个打开的文件有未保存的修改 |
:wqa 全部保存,或 :qa! 全部丢弃;只想处理那一个,用 :ls 看缓冲区编号,:b 编号 切过去 |
E173: 2 more files to edit |
用 vim a b c 一次打开了几个文件,只看了第一个 |
紧接着再输入一次 :q 即可退出,或者直接 :qa;想继续看下一个用 :n |
E45: 'readonly' option is set (add ! to override) |
文件以只读方式打开:用了 view、vim -R,打开时在交换文件警告里选了 Open Read-Only,或者当前用户没有写权限 |
执行 :!ls -l % 看权限,确认能写就 :wq!;没有权限见下一节 |
E212: Can't open file for writing |
当前用户没有写权限,或者文件所在的目录不存在 | 见下一节 |
E32: No file name |
直接执行 vim 打开了一个没有名字的空缓冲区 |
:wq ~/notes.txt 指定文件名保存退出,不要了就 :q! |
E13: File exists (add ! to override) |
用 :w 文件名 另存,目标文件已经存在 |
确认要覆盖再用 :w! 文件名 |
E492: Not an editor command: WQ |
大写锁定开着,或者命令拼错 | 关掉大写锁定重新输入 |
E514: Write error (file system full?) |
文件所在分区写满 | 不要 :q!,先 :w /dev/shm/a.conf 把内容存到内存盘,清出空间后再保存原文件 |
屏幕停在 Press ENTER or type command to continue 不是卡住,而是 Vim 在等你看完上面的消息,例如执行完 :!ls -l % 之后。按回车回到编辑界面,再输入退出命令。
E45 和 E212:没有权限时怎么把修改存下来
最常见的场景:用普通账号打开了 /etc 下的文件,改了一大段才发现忘了 sudo。不用退出重改,按情况选一种:
| 做法 | 操作 | 适合 | 注意 |
|---|---|---|---|
| 借 sudo 写回原文件 | :w !sudo tee % > /dev/null,按提示输入 sudo 密码 |
当前账号有 sudo 权限 | 写完 Vim 会提示文件在外部被改动,选 L 重新载入后 :q 退出;如果选了 O,缓冲区仍算“未保存”,此时用 :q! 退出不会丢内容,因为已经写进去了 |
| 先存一份,再拷回去 | :w /tmp/a.conf.new,:q! 退出,执行 diff /etc/a.conf /tmp/a.conf.new 核对后 sudo cp /tmp/a.conf.new /etc/a.conf |
想先确认改动再覆盖 | 用 cp 覆盖已存在的文件,原文件的属主和权限保持不变 |
| 以后从源头避免 | 编辑系统文件改用 sudoedit /etc/a.conf |
经常改配置的账号 | 以自己的身份编辑临时副本,退出时由 sudo 写回 |
tee 方式里的 % 代表当前文件名,> /dev/null 是为了不让 tee 把整个文件内容再输出到屏幕上。如果已经是 root 仍然报 E212,问题就不在 Vim 了:用 lsattr 看文件是否带不可修改属性 i,用 findmnt 看分区是否被挂成了只读,查清原因再处理。
交换文件:E325 警告与异常退出后的残留
Vim 编辑文件时会在同一目录下生成一个隐藏的交换文件,例如编辑 /etc/a.conf 时生成 /etc/.a.conf.swp,正常退出时自动删除。SSH 断线、终端被关、进程被杀,交换文件就会留下来,下次打开时出现 E325: ATTENTION,底部给出几个选项:
[O]pen Read-Only, (E)dit anyway, (R)ecover, (D)elete it, (Q)uit, (A)bort:
这个选择会直接影响之后能不能退出、会不会丢内容:
- 先看提示里的进程信息。如果写着
process ID: 2817 (STILL RUNNING),说明有人(也可能是你自己挂在后台或另一个窗口里的 Vim)正在编辑,按Q退出,不要选E硬改,否则两边各存一次,后保存的会覆盖先保存的。这种情况下 Vim 也不会给出D选项。 - 选了
O,之后保存就会报 E45。只读打开适合先看一眼,要改的话退出,处理完交换文件再重新打开。 - 选
R恢复后,交换文件不会自动删除。Vim 会提示You may want to delete the .swp file now.。先用:w /tmp/a.conf.recovered存一份,退出后diff对比,确认无误再覆盖原文件,最后手动删掉.a.conf.swp,否则下次打开还会提示。 - 确认没人在改、也不需要恢复,选
D删除交换文件,正常编辑。
想知道一台机器上还残留了哪些交换文件,执行 vim -r 会列出 Vim 能找到的交换文件;指定目录查找可以用 find /etc -name '.*.sw?'。第二个交换文件的后缀是 .swo,再往后是 .swn,看到这些说明同一个文件曾被同时打开过多次。
在 git、crontab、visudo 里打开的 Vim 怎么退出
很多命令会临时调用 Vim 让你编辑内容,退出方式决定了这次操作是生效还是作废:
| 调用方 | :wq 退出后 |
不想让这次操作生效 |
|---|---|---|
git commit |
提交完成 | :cq 退出,git 报编辑器出错并中止提交;或者删光说明文字后 :wq,git 提示 Aborting commit due to empty commit message |
crontab -e |
显示 crontab: installing new crontab,立即生效;Debian、Ubuntu 上语法有误会询问是否重新编辑 |
:q!,显示 no changes made to crontab |
visudo |
先检查语法,有错时问 What now?:e 回去修改,x 放弃本次修改并退出,Q 带着错误强行保存(危险) |
:q!,原文件不变 |
systemctl edit 服务名 |
保存为覆盖配置,并自动重新加载 systemd 配置 | :q!,不会生成覆盖文件 |
bash 的 fc 或 Ctrl+X Ctrl+E |
编辑器里的内容会立刻被当作命令执行 | 先 :%d 清空全部内容再 :wq,空内容不会执行任何命令 |
最后一行最容易出事:本想看看上一条命令,顺手 :wq,结果那条命令又执行了一遍。如果上一条是 rm 或重启服务,后果可想而知。
实在退不出来:从终端外面结束 Vim
按什么键都没有反应,先分清是 Vim 卡住还是终端卡住:
- 误按了 Ctrl+S。很多终端把它当作“暂停输出”,屏幕冻结,按 Ctrl+Q 恢复。
- SSH 连接已经僵死。网络中断后客户端可能还没察觉,依次按回车、
~、.,这是 OpenSSH 客户端断开当前连接的转义序列,然后重新登录。 - 从另一个会话结束 Vim。登录后执行
ps -ef | grep '[v]im'找到进程号,先用kill 进程号发送普通的终止信号,Vim 收到后会保留交换文件再退出,未保存的内容下次打开时可以选R恢复。只有它不理会时才用kill -9,这时交换文件里只有最近一次同步的内容:Vim 默认每输入 200 个字符,或停止输入 4 秒后同步一次。
SSH 本身登不上去时,只能从服务器本机的控制台进去。机房里的服务器可以通过 BMC 打开远程控制台,它不依赖操作系统的网络。Toplink DCIM 的 IPMI 远程管理在浏览器里打开走 BMC 通道的 VNC 控制台;管理员还能看到某台设备上有哪些在线会话用户,把多余的连接踢出。碰到交换文件提示有人正在编辑时,先看看这台设备上还有谁在线,再决定是等对方退出还是联系对方,免得两个人改同一份配置互相覆盖。
常见问题
按 Ctrl+C 或 Ctrl+Z 能退出 Vim 吗?
都不能。Ctrl+C 在 Vim 里只会取消正在输入的命令,较新的版本会在底部提示输入 :qa 或 :qa! 退出;Ctrl+Z 是把 Vim 挂到后台,屏幕回到了 shell,但 Vim 仍在运行,这时再打开同一个文件会看到交换文件警告。输入 fg 回到 Vim,再正常退出。
怎么把默认编辑器从 Vim 换成 nano?
Debian、Ubuntu 上执行 sudo update-alternatives --config editor,按编号选 nano;只想对自己的账号生效,在 ~/.bashrc 里加 export EDITOR=nano VISUAL=nano。git 有单独的设置:git config --global core.editor nano。
vi 和 vim 的退出命令一样吗?
基本一样。:wq、:x、:q、:q!、ZZ 在 vi、vim-tiny 和 BusyBox vi 里都能用;:cq、:wqa 这类命令在 BusyBox vi 里不一定支持,提示命令无效时就退回 :wq 或 :q!。