
前幾天我像往常一樣使用 Vim,突然發現了一些奇怪的事情。這就是我所做的:
~$ touch testfile
~$ ls -l | grep testfile
-rw-r--r-- 1 username groupname 0 Jul 23 10:00 testfile
~$ vim testfile
然後我做了改變,保存並退出:wq
。很正常。然而,那麼:
~$ sudo chown root:root testfile
~$ sudo chmod 644 testfile
~$ sudo -k
~$ ls -l | grep testfile
-rw-r--r-- root root 0 Jul 23 10:02 testfile
~$ vim testfile
所以root應該有讀/寫存取權限,而其他人應該只有讀取權限。編輯文件,嘗試儲存 - 你不能。太棒了,按預期工作。但是,如果您使用 儲存:w!
,vim 會以某種方式將檔案擁有權變更回 username:usergroup 並儲存檔案。即使你這樣做:
~$ sudo chmod 444 testfile
~$ sudo -k
~$ ls -l | grep testfile
-r--r--r-- 1 root root 0 Jul 23 10:06 testfile
~$ vim testfile
你可以仍然覆蓋為:w!
!怎麼了? vim 怎麼能像這樣違反文件所有權和權限的法律呢?我查看了 vim 的幫助頁面:help :w
,發現了這個:
:w[rite]! [++opt] Like ":write", but forcefully write when 'readonly' is set or there is another reason why writing was refused.
Note: This may change the permission and ownership of the file and break (symbolic) links. Add the 'W' flage to 'cpoptions' to avoid this.
我以前無法在 vim 中寫入文件,所以我想我的問題的真正核心是,如何使文件無法被 vim 編輯以及為什麼它不基於文件系統權限,就像我期望的那樣,vim 使用什麼機制來編輯其他編輯器(gedit、nano)無法使用的檔案?
編輯:我嘗試過的電腦使用的是 Linux 核心 3.15.5-2-ARCH。 Vim 的版本號是 7.4.373-1,它是由pacman
- 我沒有使用任何特殊選項從頭開始編譯的。
答案1
我可以看到您目前的路徑是~
,您的使用者的主目錄。您應該具有該目錄的寫入權限。
另一種方式思考 - 如果您對該目錄具有讀寫權限,那麼是什麼阻止您複製檔案、刪除舊檔案並使用不同的權限重命名新檔案?
如果你在 strace 下執行 vim,例如:
open("testfile", O_WRONLY|O_CREAT|O_TRUNC, 0644) = -1 EACCES (Permission denied)
lstat("testfile", {st_mode=S_IFREG|0644, st_size=10, ...}) = 0
getuid() = 1000
unlink("testfile") = 0
open("testfile", O_WRONLY|O_CREAT|O_TRUNC, 0644) = 3
write(3, "ffjidfjds\n", 10) = 10
fsync(3) = 0
close(3) = 0
chmod("testfile", 0644) = 0
根據這個日誌,我可以猜測以下過程:
chown
為了簡潔起見,省略了一些早期的權限檢查(和嘗試等)。
open
嘗試開啟檔案進行寫入(失敗:權限被拒絕)lstat
檢查文件的所有者getuuid
檢查當前使用者 ID,看看它們是否與檔案擁有者匹配unlink
刪除檔案(這是允許的,因為目錄有寫入權限)open
建立一個同名的新文件write
文件內容(之前讀過,我輸入了一些亂碼)fsync
將檔案刷新到磁碟(不是很重要)close
chmod
將新文件的權限更改為與舊文件類似 - 它現在恰好有一個新所有者。