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!。