伺服器維運

Vim 怎麼編輯檔案:從進入插入模式到儲存的完整步驟

Vim 怎麼編輯:用 vim 檔名開啟檔案,按 i 進入插入模式(底部出現 -- INSERT --)再輸入,改完按 Esc 回到普通模式,輸入 :w 儲存、:wq 儲存並退出。按 i 沒反應或儲存報錯,多半是模式不對、開啟的不是 Vim,或者當前使用者沒有寫許可權。

作者 頂聯產品團隊發布於 8 分鐘閱讀

Vim 怎麼編輯檔案,只需要記住一個迴圈:vim 檔名 開啟檔案,按 i 進入插入模式,這時螢幕左下角出現 -- INSERT --,鍵盤輸入的內容才會寫進檔案;改完按 Esc 回到普通模式,-- INSERT -- 消失;再輸入 :w 回車儲存,或者 :wq 回車儲存並退出。改亂了不想要,按 Esc 後輸入 :q! 回車,檔案保持原樣。下面用一個實際例子走一遍,再逐個解釋新手最常遇到的三類問題:按 i 沒反應、看不懂底部的提示、儲存時報唯讀或許可權錯誤。

編輯一個檔案的六個步驟

例子:在 /etc/hosts 末尾加一條解析 10.20.0.15 bmc-r01,讓這台伺服器能用名字存取一台 BMC。修改系統檔案需要 root 許可權,以 root 登入直接執行;用普通帳號的,在命令前加 sudo。

  1. 開啟檔案。 執行 vim /etc/hosts。開啟後先看最底下一行,正常會顯示檔名、行數和大小,例如 "/etc/hosts" 2L, 158B(L 是行數,B 是位元組數,老版本顯示為 C)。如果顯示的是 [New],說明檔名寫錯了,Vim 開啟的是一個不存在的新檔案;顯示 [New DIRECTORY] 則是連所在目錄都不存在。兩種情況都輸入 :q 退出,核對路徑後重新開啟;如果顯示 [readonly],說明當前使用者沒有寫許可權,先看後文“儲存失敗”一節,不要急著修改。
  2. 把游標移到要改的位置。 剛開啟時處於普通模式,按鍵是命令,不會寫進檔案。用方向鍵或 h j k l 移動;按 G 直接跳到最後一行,輸入 /localhost 回車跳到第一個 localhost 處,輸入 :5 回車跳到第 5 行。這個例子要在末尾加一行,按 G 即可。
  3. 進入插入模式。 在最後一行上按 o:Vim 在下方新開一個空行,游標停在行首,左下角出現 -- INSERT --。按哪個鍵進入插入模式,決定了從哪裡開始輸入,下一節有對照表。
  4. 輸入內容。 輸入 10.20.0.15 bmc-r01。插入模式下可以用退格鍵刪掉剛輸錯的字元,也可以用方向鍵移動游標,和普通編輯器一樣。
  5. 回到普通模式。 按 Esc,左下角的 -- INSERT -- 消失。只要還要執行儲存、查詢、撤銷之類的命令,就必須先回到普通模式。
  6. 儲存。 輸入 :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 修改後儲存,會依次看到這幾條提示:

  1. 開啟時底部顯示 [readonly]:Vim 檢測到當前使用者對這個檔案沒有寫許可權。
  2. 按 i 開始輸入時出現 W10: Warning: Changing a readonly file:這只是警告,Vim 仍然允許修改緩衝區裡的內容。
  3. 輸入 :w 時報 E45: 'readonly' option is set (add ! to override):儲存被拒絕。
  4. 按提示改用 :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 退出,不會產生任何修改。

想看看在你的機房裡怎麼用?

從一次產品示範開始,梳理你的業務鏈路。

查看價格
服務熱線 400-112-2951

讓我們聊聊你的 IDC 業務

掃碼新增企業微信,預約產品示範或申請試用。

Toplink 企業微信二維碼

長按儲存或使用企業微信 / 微信掃描

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