Vim 怎麼編輯檔案:從進入插入模式到儲存的完整步驟
Vim 怎麼編輯:用 vim 檔名開啟檔案,按 i 進入插入模式(底部出現 -- INSERT --)再輸入,改完按 Esc 回到普通模式,輸入 :w 儲存、:wq 儲存並退出。按 i 沒反應或儲存報錯,多半是模式不對、開啟的不是 Vim,或者當前使用者沒有寫許可權。
Vim 怎麼編輯檔案,只需要記住一個迴圈:vim 檔名 開啟檔案,按 i 進入插入模式,這時螢幕左下角出現 -- INSERT --,鍵盤輸入的內容才會寫進檔案;改完按 Esc 回到普通模式,-- INSERT -- 消失;再輸入 :w 回車儲存,或者 :wq 回車儲存並退出。改亂了不想要,按 Esc 後輸入 :q! 回車,檔案保持原樣。下面用一個實際例子走一遍,再逐個解釋新手最常遇到的三類問題:按 i 沒反應、看不懂底部的提示、儲存時報唯讀或許可權錯誤。
編輯一個檔案的六個步驟
例子:在 /etc/hosts 末尾加一條解析 10.20.0.15 bmc-r01,讓這台伺服器能用名字存取一台 BMC。修改系統檔案需要 root 許可權,以 root 登入直接執行;用普通帳號的,在命令前加 sudo。
- 開啟檔案。 執行
vim /etc/hosts。開啟後先看最底下一行,正常會顯示檔名、行數和大小,例如"/etc/hosts" 2L, 158B(L 是行數,B 是位元組數,老版本顯示為 C)。如果顯示的是[New],說明檔名寫錯了,Vim 開啟的是一個不存在的新檔案;顯示[New DIRECTORY]則是連所在目錄都不存在。兩種情況都輸入:q退出,核對路徑後重新開啟;如果顯示[readonly],說明當前使用者沒有寫許可權,先看後文“儲存失敗”一節,不要急著修改。 - 把游標移到要改的位置。 剛開啟時處於普通模式,按鍵是命令,不會寫進檔案。用方向鍵或
hjkl移動;按G直接跳到最後一行,輸入/localhost回車跳到第一個 localhost 處,輸入:5回車跳到第 5 行。這個例子要在末尾加一行,按G即可。 - 進入插入模式。 在最後一行上按
o:Vim 在下方新開一個空行,游標停在行首,左下角出現-- INSERT --。按哪個鍵進入插入模式,決定了從哪裡開始輸入,下一節有對照表。 - 輸入內容。 輸入
10.20.0.15 bmc-r01。插入模式下可以用退格鍵刪掉剛輸錯的字元,也可以用方向鍵移動游標,和普通編輯器一樣。 - 回到普通模式。 按
Esc,左下角的-- INSERT --消失。只要還要執行儲存、查詢、撤銷之類的命令,就必須先回到普通模式。 - 儲存。 輸入
:w回車,底部顯示類似"/etc/hosts" 3L, 178B written,說明已經寫入磁碟;輸入:wq回車是儲存並退出,:q!回車是放棄修改退出。
退出 Vim 後確認一下結果:
tail -n 2 /etc/hosts # 看最後兩行,新加的一行應在末尾
getent hosts bmc-r01 # 按系統的解析順序查詢,能返回 10.20.0.15 說明生效
/etc/hosts 儲存後對新的解析請求立即生效,不需要重啟任何服務。其他檔案儲存後怎麼生效,見文末的表格。
i、a、o 選哪個:同一行上的差別
進入插入模式的鍵有好幾個,區別只在於“從哪裡開始輸入”。假設當前行是 127.0.0.1 localhost,游標停在 localhost 的第一個字母 l 上,按下表中的鍵後輸入 X 再按 Esc,結果分別是:
| 按鍵 | 從哪裡開始輸入 | 這一行變成 |
|---|---|---|
i |
游標所在字元的前面 | 127.0.0.1 Xlocalhost |
a |
游標所在字元的後面 | 127.0.0.1 lXocalhost |
I |
行首第一個非空字元前面 | X127.0.0.1 localhost |
A |
行尾 | 127.0.0.1 localhostX |
o |
在下方新開一行 | 原行不變,下一行是 X |
O |
在上方新開一行 | 原行不變,上一行是 X |
s |
先刪掉游標處的一個字元 | 127.0.0.1 Xocalhost |
cw |
先刪掉從游標到詞尾的內容 | 127.0.0.1 X |
R |
進入替換模式,輸入的字元逐個覆蓋原字元 | 127.0.0.1 Xocalhost,底部顯示 -- REPLACE -- |
按改動的型別選鍵,能少按很多次方向鍵:
- 改一個值(連接埠號、開關),把游標放到值的第一個字元上按
cw,直接輸入新值。游標停在值的中間時,cw只會替換後半截。IP 位址、路徑這類帶.、/的值,cw遇到這些符號就停下,要改用大寫的cW,它一直替換到下一個空格之前。 - 在行尾補引數,按
A,不用先把游標挪到行尾。 - 新增一行配置,在相關的那一行上按
o,新行緊跟在它下面,層級和上下文都清楚。 - 只換一個字元,不必進入插入模式:按
r再按新字元,例如把0改成1就是r1。
底部的提示分別是什麼意思
Vim 用螢幕最下面一行告訴你當前處於什麼狀態。看懂這一行,大部分“按鍵沒反應”“輸入亂了”的問題就有了方向:
| 底部顯示 | 當前狀態 | 接下來怎麼做 |
|---|---|---|
| 什麼都沒有 | 普通模式,按鍵都是命令 | 要輸入文字先按 i、a、o 等 |
-- INSERT --(中文介面為 -- 插入 --) |
插入模式,輸入的內容直接寫進檔案 | 輸入完按 Esc |
-- REPLACE -- |
替換模式,輸入會覆蓋原有字元;按了 R,或在插入模式下按了鍵盤上的 Insert 鍵 |
按 Esc 退出,被覆蓋的內容用 u 撤回 |
-- VISUAL --、-- VISUAL LINE --、-- VISUAL BLOCK -- |
可視模式,正在選中文字 | 按 Esc 取消選擇 |
-- (insert) -- |
在插入模式下按了 Ctrl+O,臨時執行一條普通模式命令 |
執行完會自動回到插入模式 |
recording @q |
按了 q 再按一個字母,正在錄製宏 |
再按一次 q 停止錄製,對檔案沒有影響 |
游標在最後一行,行首是 : 或 / |
命令列模式,正在輸入命令或查詢內容 | 回車執行,Esc 放棄 |
"檔名" [New] 或 [New DIRECTORY] |
檔案不存在,開啟的是一個新的空檔案;後者表示所在目錄也不存在 | 核對路徑,拼錯了就 :q 退出重開 |
"檔名" [readonly] |
對檔案沒有寫許可權,或以唯讀方式開啟 | 見“儲存失敗”一節 |
"檔名" [Permission Denied] |
連讀許可權都沒有,螢幕上是空白 | :q 退出,用有許可權的帳號重新開啟 |
按 i 沒反應:按現象逐個排查
“按 i 沒反應”其實是好幾種不同的情況,先看清現象再處理:
| 現象 | 原因 | 處理 |
|---|---|---|
按 i 後底部沒有任何提示,但接著輸入的字母確實出現在檔案裡;或者在插入模式下按方向鍵,冒出 A、B、C、D 和空行 |
用 vi 命令開啟、系統裡只裝了精簡版 vim-tiny(Debian、Ubuntu 最小安裝常見),它以 vi 相容方式執行:不顯示模式提示,插入模式下的方向鍵也不能用 |
其實已經在插入模式,照常輸入;要移動游標先按 Esc 回到普通模式。輸入 :set showmode 可以開啟提示,徹底解決就安裝完整版 apt install vim |
按 i 後檔案裡多出一個字母 i |
本來就在插入模式 | 按 Esc,再按 u 撤銷多出來的字元 |
底部出現 Entering Ex mode. Type "visual" to go to Normal mode.,之後輸入的內容只在底部回顯 |
在普通模式下誤按了大寫 Q,進入了 Ex 模式 |
輸入 visual 回車,回到普通模式 |
按 i 後底部提示 E21: Cannot make changes, 'modifiable' is off |
用 vim -M 開啟,或者當前視窗是目錄列表、幫助文件,不允許修改 |
確認開啟的是檔案本身;確實要改,執行 :set modifiable |
| 按什麼鍵螢幕都不動 | 按過 Ctrl+S,終端暫停了輸出;或者 SSH 連線已經斷開 |
先按 Ctrl+Q 恢復;還不動就是連線斷了,依次按回車、~、. 斷開這個會話,重新登入 |
底部有 ^O Write Out、^X Exit 字樣 |
開啟的是 nano 而不是 Vim,常見於 crontab -e、visudo |
在 nano 裡直接輸入即可,Ctrl+O 儲存、Ctrl+X 退出;想改用 Vim,執行 export EDITOR=vim,Ubuntu 上的 crontab 也可以用 select-editor 選擇 |
底部是 (END) 或一個冒號,只能上下翻頁 |
是 less 分頁器,例如 systemctl cat、git log、man 的輸出 |
按 q 退出,它本來就不能編輯 |
Esc 按了不管用,瀏覽器反而退出了全屏 |
在網頁版的遠端控制檯裡操作,Esc 被瀏覽器攔截 |
用 Ctrl+[ 代替 Esc,兩者在終端裡發出的是同一個字元 |
按 : 後底部沒有出現冒號,或者輸入命令後報 E492: Not an editor command |
輸入法處於中文狀態,打出的是全形冒號或全形字母 | 切換到英文輸入法,按 Esc 後重新輸入 |
最後兩行在遠端控制檯和中文系統上特別常見。用 BMC 的網頁控制檯救機時,鍵盤事件要經過瀏覽器、控制檯程式再到伺服器,Esc、F 鍵和組合鍵都可能被中間環節截走,Ctrl+[ 這個替代鍵值得記住。
儲存失敗:唯讀、許可權和磁碟
普通使用者忘了加 sudo,開啟 /etc/hosts 修改後儲存,會依次看到這幾條提示:
- 開啟時底部顯示
[readonly]:Vim 檢測到當前使用者對這個檔案沒有寫許可權。 - 按
i開始輸入時出現W10: Warning: Changing a readonly file:這只是警告,Vim 仍然允許修改緩衝區裡的內容。 - 輸入
:w時報E45: 'readonly' option is set (add ! to override):儲存被拒絕。 - 按提示改用
:w!:檔案屬於你自己時(例如你把自己的檔案設成了唯讀),Vim 會寫入成功;檔案屬於 root 時報E212: Can't open file for writing,!繞不過系統許可權。
已經改了一大段,不想重來,先把內容存到自己有許可權的地方:輸入 :w /tmp/hosts.new 回車,退出後執行 sudo cp /tmp/hosts.new /etc/hosts。cp 覆蓋已存在的檔案時保留目標檔案原來的屬主和許可權,不會把 /etc/hosts 變成你的檔案。以後編輯系統檔案,直接用 sudoedit /etc/hosts(等同於 sudo -e):sudo 先把檔案複製成臨時檔案,用你自己的身份和 ~/.vimrc 開啟編輯,退出時再寫回原位置,用哪個編輯器由 SUDO_EDITOR、VISUAL 或 EDITOR 環境變數決定。
root 也存不進去,或者報的是別的錯誤,按下表檢查:
| 現象 | 原因 | 檢查 | 處理 |
|---|---|---|---|
root 使用者 :w 仍報寫入失敗 |
檔案帶有不可修改屬性(immutable) | lsattr /etc/hosts,屬性裡有 i |
chattr -i /etc/hosts 後再儲存,需要時改完再加回去;不是你們自己設定的,要排查是不是被入侵後有人鎖定了檔案 |
報 E212,開啟時底部顯示 [New DIRECTORY] |
檔案所在的目錄不存在,多半是路徑拼錯 | 看底部的完整路徑 | 路徑錯了就重開;確實要新建目錄,執行 :!mkdir -p %:h 再 :w,%:h 表示當前檔案所在的目錄 |
| root 儲存失敗,同一分割槽上的其他檔案也寫不進去 | 檔案系統被掛載為唯讀,常見於磁碟出錯後核心自動改成唯讀 | findmnt -no OPTIONS / 的輸出裡有 ro;dmesg 裡有 Remounting filesystem read-only 一類的記錄 |
先查清磁碟和檔案系統錯誤,不要直接 remount 成讀寫繼續寫入 |
報 E514: Write error (file system full?) |
磁碟或分割槽寫滿 | df -h /etc;空間還有但仍失敗時看 df -i,可能是 inode 用完 |
不要 :q!,先 :w /dev/shm/hosts.tmp 把內容存進記憶體盤,清理空間後再儲存原檔案 |
改錯了怎麼退回
在儲存之前,Vim 能幫你撤回;儲存並退出之後,就只能靠備份了。
- 撤銷與重做:普通模式下按
u撤銷上一步,可以連續按;撤銷過頭了按Ctrl+r重做。 - 儲存前看看改了什麼:輸入
:w !diff % -回車,把當前緩衝區的內容交給 diff,和磁碟上的檔案對比,按回車回到編輯介面。改了很多處、不確定有沒有誤改時,這一步比來回翻頁可靠。 - 回到上一次儲存時的狀態:
:earlier 1f把內容退回到最近一次:w時的樣子,適合“儲存過一次、之後越改越亂”的情況。 - 全部不要了:
:e!丟棄所有未儲存的修改,從磁碟重新載入;:q!直接退出。
Vim 預設在退出後不保留撤銷記錄,所以改重要配置前先做一份備份:cp -a /etc/hosts /etc/hosts.$(date +%F),-a 連同許可權和時間戳一起保留。
儲存之後:不同檔案的生效方式
儲存只是把內容寫進磁碟,修改什麼時候生效、用什麼方式編輯更安全,各類檔案不一樣:
| 檔案 | 推薦的編輯方式 | 儲存後要做什麼 |
|---|---|---|
/etc/hosts |
直接用 Vim | 立即生效,用 getent hosts 主機名 驗證 |
/etc/sudoers 及 /etc/sudoers.d/ 下的檔案 |
visudo,想用 Vim 就執行 EDITOR=vim visudo |
visudo 儲存時檢查語法,有錯會問 What now?,按 e 回去修改;不要用 Vim 直接改,寫錯後所有人都用不了 sudo |
| 計劃任務 | crontab -e,不要直接改 /var/spool/cron 下的檔案 |
退出時提示 crontab: installing new crontab 即已生效 |
/etc/fstab |
直接用 Vim,改前備份 | findmnt --verify 檢查格式,systemctl daemon-reload 讓 systemd 重新讀取,再 mount -a 試掛載,沒有報錯再重啟 |
| systemd 服務配置 | systemctl edit 服務名,生成單獨的覆蓋檔案 |
編輯器退出後自動重新載入配置,再 systemctl restart 服務名 |
| sshd、nginx 等服務的配置 | 直接用 Vim,改前備份 | 先用 sshd -t、nginx -t 檢查語法,透過後再 reload |
fstab 和 sudoers 寫錯的代價最大:前者可能讓伺服器開機進入緊急模式、SSH 連不上,後者會讓所有人失去 sudo。遇到這種情況只能從本機控制檯登入改回來。機房裡的伺服器可以透過 BMC 的遠端控制檯操作,在 Toplink DCIM 的 IPMI 遠端管理裡,VNC 控制檯走 BMC 通道,開機自檢、緊急模式的命令列都能看到,進去後用本文的方法開啟檔案、改回、儲存即可;遇到 Esc 被瀏覽器攔截的情況,記得換成 Ctrl+[。
常見問題
Vim 裡怎麼把整個檔案清空重寫?
普通模式下按 gg 回到第一行,再按 dG 刪除到檔案末尾,然後按 i 輸入新內容。也可以輸入 :%d 回車,效果相同。清空前先確認檔案有備份,誤刪後在儲存之前按 u 可以撤回。
編輯時不小心按了 Ctrl+Z,Vim 不見了怎麼辦?
Ctrl+Z 把 Vim 掛到了後台,沒有退出,修改也還在。在終端輸入 fg 回車就能回到編輯介面;jobs 命令可以看到後台掛著哪些程式。不要在掛起狀態下另開一個 Vim 編輯同一個檔案,否則會出現交換檔案提示。
只想看檔案內容、不想改,用什麼開啟更安全?
用 view 檔名 或 vim -R 檔名 以唯讀方式開啟,誤按 :w 會被拒絕;只是翻看日誌,用 less 更合適,按 / 查詢、按 q 退出,不會產生任何修改。