服务器运维

Vim 怎么退出?保存退出、不保存退出与 wq 退不出来怎么办

Vim 怎么退出:先按 Esc 回到普通模式,输入 :wq 回车是保存并退出,输入 :q! 回车是放弃修改直接退出。输入 :wq 后还停在 Vim 里,就看屏幕最底下一行:E37 是改动没保存,E45 是只读,E212 是没有写权限,E32 是文件还没有名字,按提示对应处理即可。

作者 顶联产品团队发布于 7 分钟阅读

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:

这个选择会直接影响之后能不能退出、会不会丢内容:

  1. 先看提示里的进程信息。如果写着 process ID: 2817 (STILL RUNNING),说明有人(也可能是你自己挂在后台或另一个窗口里的 Vim)正在编辑,按 Q 退出,不要选 E 硬改,否则两边各存一次,后保存的会覆盖先保存的。这种情况下 Vim 也不会给出 D 选项。
  2. 选了 O,之后保存就会报 E45。只读打开适合先看一眼,要改的话退出,处理完交换文件再重新打开。
  3. 选 R 恢复后,交换文件不会自动删除。Vim 会提示 You may want to delete the .swp file now.。先用 :w /tmp/a.conf.recovered 存一份,退出后 diff 对比,确认无误再覆盖原文件,最后手动删掉 .a.conf.swp,否则下次打开还会提示。
  4. 确认没人在改、也不需要恢复,选 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!。

想看看在你的机房里怎么用?

从一次产品演示开始,梳理你的业务链路。

查看价格
服务热线 400-112-2951

让我们聊聊你的 IDC 业务

扫码添加企业微信,预约产品演示或申请试用。

Toplink 企业微信二维码

长按保存或使用企业微信 / 微信扫描

也可致电
400-112-2951
Telegram
@TopLink88