大家先了解一些背景知識:
1) 給文件增加了i權限,那文件不能被更改,不能刪除,也不能修改名字以及權限。
2) 給文件增加a權限,文件可以追加內容,不能刪除,不能修改內容,不能修改名字以及權限。
3) vim一個文件,如果不正常退出,再次編輯時是會提示一些信息的,并且有一個隱藏的文件.xxx.swp
了解以上知識后,再來看下面的現象:
1) 如果給一個文件增加a權限,用vim編輯文件,增加內容(注意是在文件末尾增加內容,不要修改其他內容),并不會成功。
2) 如果給一個目錄增加i權限或者a權限,在該目錄下面vim一個文件,更改文件內容可以正常保存。
既然a權限可以追加內容,那為何vim一個文件在末尾增加內容不能成功?既然i權限不能修改,那為何在目錄里面變更文件內容卻可以成功?
關于這兩點,你有沒有疑惑?下面我們來分析原因。
先不管i或者a權限,
在一個沒有i或者a權限的目錄下,編輯一個沒有i或者a權限的文件,
用strace來查看其執行過程。
mkdir /tmp/test
strace vim /tmp/test/aminglinux.txt 2>/tmp/vim.log
寫入一個數字1,然后保存退出。再來查看vim.log的內容。
less /tmp/vim.log
大部分內容你不用關心,只需要看這幾行:
stat("/tmp/test/aminglinux.txt", 0x7fff072ecb10) = -1 ENOENT (No such file or directory)
access("/tmp/test/aminglinux.txt", W_OK) = -1 ENOENT (No such file or directory)
open("/tmp/test/aminglinux.txt", O_RDONLY) = -1 ENOENT (No such file or directory)
readlink("/tmp/test/aminglinux.txt", 0x7fff072eb360, 4095) = -1 ENOENT (No such file or directory)
open("/tmp/test/.aminglinux.txt.swp", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/tmp/test/.aminglinux.txt.swp", O_RDWR|O_CREAT|O_EXCL, 0600) = 3
open("/tmp/test/.aminglinux.txt.swx", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/tmp/test/.aminglinux.txt.swx", O_RDWR|O_CREAT|O_EXCL, 0600) = 4
unlink("/tmp/test/.aminglinux.txt.swx") = 0
unlink("/tmp/test/.aminglinux.txt.swp") = 0
stat("/tmp/test/.aminglinux.txt.swp", 0x7fff072ec310) = -1 ENOENT (No such file or directory)
lstat("/tmp/test/.aminglinux.txt.swp", 0x7fff072ec3e0) = -1 ENOENT (No such file or directory)
lstat("/tmp/test/.aminglinux.txt.swp", 0x7fff072ec8a0) = -1 ENOENT (No such file or directory)
open("/tmp/test/.aminglinux.txt.swp", O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW, 0600) = 3
stat("/tmp/test/aminglinux.txt", 0x7fff072eac40) = -1 ENOENT (No such file or directory)
stat("/tmp/test/aminglinux.txt", 0x7fff072ebe20) = -1 ENOENT (No such file or directory)
stat("/tmp/test/aminglinux.txt", 0x7fff072eadf0) = -1 ENOENT (No such file or directory)
write(1, ""/tmp/test/aminglinux.txt"", 26) = 26
stat("/tmp/test/aminglinux.txt", 0x7fff072ec050) = -1 ENOENT (No such file or directory)
open("/tmp/test/aminglinux.txt", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 4
stat("/tmp/test/aminglinux.txt", {st_mode=S_IFREG|0644, st_size=2, ...}) = 0
stat("/tmp/test/aminglinux.txt", {st_mode=S_IFREG|0644, st_size=2, ...}) = 0
unlink("/tmp/test/.aminglinux.txt.swp") = 0
看起來亂亂的,其實大概的過程就是vim /tmp/test/aminglinux.txt時,先看有沒有.aminglinux.txt.swp以及.aminglinux.txt.swx,因為這兩個文件就是vim產生的臨時文件,swp先產生,如果swp存在就產生第二個swx。寫入的內容先存到swp里,當保存退出vim時,再把swp的內容存到aminglinux.txt里,最后刪除掉swp文件。
有了這個認識之后,我們再來分析上面提到的現象1。如果文件給了a權限,那么在編輯該文件時,會產生swp文件,當保存退出時,swp文件內容會寫入該文件,這相當于更改該文件,很線上a權限是不允許的。
再來分析現象2,按照我們的推測,如果目錄給了a權限,增加文件沒問題,也就是說產生swp或者swx文件沒有問題,當然把swp或者swx內容寫入到文件里時也不會有問題,但swp或者swx文件卻不會被刪除了,所以再次編輯文件時就會提示臨時文件已經存在了。但這并不會影響修改文件內容。
如果給目錄設置了i權限的話,vim編輯文件,要產生swp或swx肯定會出錯啊,但為何依然能正常編輯文件? 下面繼續用strace來分析一下。
chattr +i /tmp/test
strace vim /tmp/test/aminglinux.txt 2> /tmp/vim.log
看vim.log里面和aminglinux.txt相關的信息
stat("/tmp/test/aminglinux.txt", {st_mode=S_IFREG|0644, st_size=4, ...}) = 0
stat("/tmp/test/aminglinux.txt", {st_mode=S_IFREG|0644, st_size=4, ...}) = 0
stat("/tmp/test/aminglinux.txt", {st_mode=S_IFREG|0644, st_size=4, ...}) = 0
stat("/tmp/test/aminglinux.txt", {st_mode=S_IFREG|0644, st_size=4, ...}) = 0
access("/tmp/test/aminglinux.txt", W_OK) = 0
open("/tmp/test/aminglinux.txt", O_RDONLY) = 3
readlink("/tmp/test/aminglinux.txt", 0x7fff49efc6f0, 4095) = -1 EINVAL (Invalid argument)
open("/tmp/test/.aminglinux.txt.swp", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/tmp/test/.aminglinux.txt.swp", O_RDWR|O_CREAT|O_EXCL, 0600) = -1 EACCES (Permission denied)
stat("/tmp/test/.aminglinux.txt.swp", 0x7fff49efd6a0) = -1 ENOENT (No such file or directory)
lstat("/tmp/test/.aminglinux.txt.swp", 0x7fff49efd770) = -1 ENOENT (No such file or directory)
lstat("/tmp/test/.aminglinux.txt.swp", 0x7fff49efdc30) = -1 ENOENT (No such file or directory)
open("/tmp/test/.aminglinux.txt.swp", O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW, 0600) = -1 EACCES (Permission denied)
readlink("/tmp/test/aminglinux.txt", 0x7fff49efc6f0, 4095) = -1 EINVAL (Invalid argument)
open("/root/tmp/aminglinux.txt.swp", O_RDONLY) = -1 ENOTDIR (Not a directory)
open("/root/tmp/aminglinux.txt.swp", O_RDWR|O_CREAT|O_EXCL, 0600) = -1 ENOTDIR (Not a directory)
stat("/root/tmp/aminglinux.txt.swp", 0x7fff49efd6a0) = -1 ENOTDIR (Not a directory)
lstat("/root/tmp/aminglinux.txt.swp", 0x7fff49efd770) = -1 ENOTDIR (Not a directory)
lstat("/root/tmp/aminglinux.txt.swp", 0x7fff49efdc30) = -1 ENOTDIR (Not a directory)
open("/root/tmp/aminglinux.txt.swp", O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW, 0600) = -1 ENOTDIR (Not a directory)
readlink("/tmp/test/aminglinux.txt", 0x7fff49efc6f0, 4095) = -1 EINVAL (Invalid argument)
open("/var/tmp/aminglinux.txt.swp", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/var/tmp/aminglinux.txt.swp", O_RDWR|O_CREAT|O_EXCL, 0600) = 4
open("/var/tmp/aminglinux.txt.swx", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/var/tmp/aminglinux.txt.swx", O_RDWR|O_CREAT|O_EXCL, 0600) = 5
unlink("/var/tmp/aminglinux.txt.swx") = 0
unlink("/var/tmp/aminglinux.txt.swp") = 0
stat("/var/tmp/aminglinux.txt.swp", 0x7fff49efd6a0) = -1 ENOENT (No such file or directory)
lstat("/var/tmp/aminglinux.txt.swp", 0x7fff49efd770) = -1 ENOENT (No such file or directory)
lstat("/var/tmp/aminglinux.txt.swp", 0x7fff49efdc30) = -1 ENOENT (No such file or directory)
open("/var/tmp/aminglinux.txt.swp", O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW, 0600) = 4
chmod("/var/tmp/aminglinux.txt.swp", 0644) = 0
open("/tmp/test/aminglinux.txt", O_RDONLY) = 3
stat("/tmp/test/aminglinux.txt", {st_mode=S_IFREG|0644, st_size=4, ...}) = 0
stat("/tmp/test/aminglinux.txt", {st_mode=S_IFREG|0644, st_size=4, ...}) = 0
stat("/tmp/test/aminglinux.txt", {st_mode=S_IFREG|0644, st_size=4, ...}) = 0
access("/tmp/test/aminglinux.txt", W_OK) = 0
write(1, ""aminglinux.txt"", 16) = 16
stat("aminglinux.txt", {st_mode=S_IFREG|0644, st_size=4, ...}) = 0
access("aminglinux.txt", W_OK) = 0
getxattr("aminglinux.txt", "system.posix_acl_access", 0x7fff49efd050, 132) = -1 ENODATA (No data available)
stat("aminglinux.txt", {st_mode=S_IFREG|0644, st_size=4, ...}) = 0
open("aminglinux.txt", O_WRONLY|O_CREAT|O_TRUNC, 0644) = 3
chmod("aminglinux.txt", 0100644) = 0
setxattr("aminglinux.txt", "system.posix_acl_access", "x02x00x00x00x01x00x06x00xffxffxffxffx04x00x04x00xffxffxffxff x00x04x00xffxffxffxff", 28, 0) = 0
stat("/tmp/test/aminglinux.txt", {st_mode=S_IFREG|0644, st_size=6, ...}) = 0
unlink("/var/tmp/aminglinux.txt.swp") = 0
我相信你可以看到Permission denied的提示,這是因為當前目錄有i權限,不能增加文件,也就不能在當前目錄下生成臨時文件。當然,vim如果遇到這樣的問題,它還是會“曲線救國”的,于是先找/root/tmp/,但是并沒有該目錄,只好繼續找/var/tmp/,這個目錄存在,所以就在這個目錄里生成了臨時文件(并不是隱藏的)。后面的操作就不用多說了。
既然vim可以在/var/tmp/下生成臨時文件,自然也可以在已經設置了i權限的目錄里編輯文件的,這樣現象2也解釋通了。上面羅嗦了這么多,其實我就想表達如下觀點:
vim編輯文件時,會在該文件所在目錄生成臨時隱藏文件.swp和.swx,如果那目錄不可寫就會到/root/tmp/下或者/var/tmp/下生成臨時文件(非隱藏),當編輯的文件保存后,臨時文件刪除。
-
Linux
+關注
關注
87文章
11345瀏覽量
210383 -
VIM
+關注
關注
0文章
134瀏覽量
15350
原文標題:你所不知道的vim小秘密
文章出處:【微信號:aming_linux,微信公眾號:阿銘linux】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論