用vim保存文件和echo命令到底有什麼不一樣?

原文地址:silenceper.com/blog/202005…node

微信公衆號:學點程序git

現象

最近在調試一個filebeat程序時須要製造一些log,我是直接使用vim直接對文件打開而後直接保存的。github

可是有個奇怪的現象:每次寫入一行新的日誌,filebeat都會將整個文件的內容又從新進行上報一遍致使日誌上傳重複,同時觀察到filebeat的文件採集狀態文件registry都會進行增長一個重複的文件(source相同,inode不一樣)。golang

操做一番後覺得是程序的問題,最後才反應過來(一開始沒注意到inode不一樣 :<),最終使用echo "test some log">>test.log追加的方式發現不會有此問題。shell

同時看了下二者的inode信息,確認了是由於vim會改變文件的inode(一個新的文件),echo則不會:vim

2020-05-14更新:也跟文件權限有關,若是文件沒有o沒有w權限,則inode信息會改變,若是chmod o+w test.log則inode信息不會變bash

同時vim也是開了備份文件微信

一、查看文件inode爲908488工具

[root@localhost work]# stat test.log
  文件:"test.log"
  大小:0         	塊:0          IO 塊:4096   普通空文件
設備:fd00h/64768d	Inode:908488      硬連接:1
權限:(0644/-rw-r--r--)  Uid:(    0/    root)   Gid:(    0/    root)
環境:unconfined_u:object_r:admin_home_t:s0
最近訪問:2020-05-10 04:38:39.399791808 -0400
最近更改:2020-05-10 04:38:39.399791808 -0400
最近改動:2020-05-10 04:38:39.399791808 -0400
建立時間:-
複製代碼

二、當我用vim/vi工具進行編輯保存以後,變爲了:908490this

[root@localhost work]# vi test.log
[root@localhost work]# stat test.log
  文件:"test.log"
  大小:7         	塊:8          IO 塊:4096   普通文件
設備:fd00h/64768d	Inode:908490      硬連接:1
權限:(0644/-rw-r--r--)  Uid:(    0/    root)   Gid:(    0/    root)
環境:unconfined_u:object_r:admin_home_t:s0
最近訪問:2020-05-10 04:39:01.950055784 -0400
最近更改:2020-05-10 04:39:01.950055784 -0400
最近改動:2020-05-10 04:39:01.953305882 -0400
建立時間:-
複製代碼

三、而用echo命令修改看到inode信息並無改變, 908490

[root@localhost work]# echo "test some log">>test.log
[root@localhost work]# stat test.log
  文件:"test.log"
  大小:21        	塊:8          IO 塊:4096   普通文件
設備:fd00h/64768d	Inode:908490      硬連接:1
權限:(0644/-rw-r--r--)  Uid:(    0/    root)   Gid:(    0/    root)
環境:unconfined_u:object_r:admin_home_t:s0
最近訪問:2020-05-10 04:39:01.950055784 -0400
最近更改:2020-05-10 04:41:16.794459151 -0400
最近改動:2020-05-10 04:41:16.794459151 -0400
建立時間:-
複製代碼

驗證

其實經過inode的改變以及能夠猜想出在使用vi/vim進行編輯的時候,文件以及變爲了一個新的文件,這裏我主要經過inotifywait來看一下,在進行vim編輯的時候,文件會產生什麼時間

一開始原本打算使用golang中github.com/fsnotify/fsnotify去看的,可是發現包中對event進行了合併,不夠原始。因此才直接使用inotifywait來看

inotifywait命令:

inotifywait -rm test.log
複製代碼

文件權限:

-rw-r--r--. 1 root root   49 5月  14 05:40 test.log
複製代碼

一、使用vim進行編輯的結果:

[root@localhost work]# inotifywait -rm test.log
Setting up watches.  Beware: since -r was given, this may take a while!
Watches established.
test.log OPEN
test.log ACCESS
test.log CLOSE_NOWRITE,CLOSE
test.log MOVE_SELF
test.log ATTRIB
test.log DELETE_SELF
複製代碼

能夠看到對文件進行了DELETE_SELF

注意當再次進行編輯的時候,已經沒法監聽到了,由於原有文件已經被刪除,須要從新監聽

二、使用echo進行追加寫入的結果

[root@localhost work]# inotifywait -rm test.log
Setting up watches.  Beware: since -r was given, this may take a while!
Watches established.
test.log OPEN
test.log MODIFY
test.log CLOSE_WRITE,CLOSE
複製代碼

三、監聽整個目錄,能夠看到更多信息

[root@localhost work]# inotifywait -rm ./dir/
Setting up watches.  Beware: since -r was given, this may take a while!
Watches established.

# 當進行文件寫入時
./dir/ OPEN test.log
./dir/ CREATE .test.log.swp
./dir/ OPEN .test.log.swp
./dir/ CREATE .test.log.swx
./dir/ OPEN .test.log.swx
./dir/ CLOSE_WRITE,CLOSE .test.log.swx
./dir/ DELETE .test.log.swx
./dir/ CLOSE_WRITE,CLOSE .test.log.swp
./dir/ DELETE .test.log.swp
./dir/ CREATE .test.log.swp
./dir/ OPEN .test.log.swp
./dir/ MODIFY .test.log.swp
./dir/ ATTRIB .test.log.swp
./dir/ ACCESS test.log
./dir/ CLOSE_NOWRITE,CLOSE test.log
./dir/ MODIFY .test.log.swp

# 當進行文件保存是

./dir/ CREATE 4913
./dir/ OPEN 4913
./dir/ ATTRIB 4913
./dir/ CLOSE_WRITE,CLOSE 4913
./dir/ DELETE 4913
./dir/ MOVED_FROM test.log
./dir/ MOVED_TO test.log~
./dir/ CREATE test.log
./dir/ OPEN test.log
./dir/ MODIFY test.log
./dir/ CLOSE_WRITE,CLOSE test.log
./dir/ ATTRIB test.log
./dir/ MODIFY .test.log.swp
./dir/ DELETE test.log~
./dir/ CLOSE_WRITE,CLOSE .test.log.swp
./dir/ DELETE .test.log.swp
複製代碼

能夠看到在進行文件保存時,將原有test.log 移動爲test.log~,並新建立一個文件test.log,最後對test.log~備份文件和.test.log.swp緩衝區文件進行刪除

四、當進行chmod o+w test.log時,看到的信息以下:

./dir/ CREATE 4913
./dir/ OPEN 4913
./dir/ ATTRIB 4913
./dir/ CLOSE_WRITE,CLOSE 4913
./dir/ DELETE 4913
./dir/ OPEN test.log
./dir/ CREATE test.log~
./dir/ OPEN test.log~
./dir/ ATTRIB test.log~
./dir/ ACCESS test.log
./dir/ MODIFY test.log~
./dir/ CLOSE_WRITE,CLOSE test.log~
./dir/ ATTRIB test.log~
./dir/ CLOSE_NOWRITE,CLOSE test.log
./dir/ MODIFY test.log
./dir/ OPEN test.log
./dir/ MODIFY test.log
./dir/ CLOSE_WRITE,CLOSE test.log
./dir/ ATTRIB test.log
./dir/ MODIFY .test.log.swp
./dir/ DELETE test.log~
./dir/ CLOSE_WRITE,CLOSE .test.log.swp
./dir/ DELETE .test.log.swp
複製代碼

對比3中的結果沒有將test.log move to test.log~的操做,而是直接對test.log文件進行更改,因此此時inode信息並無改變

五、若是關閉vim備份

經過設置vim參數set nobackup nowritebackup關閉vim的備份,則在保存的時候不會生成test.log~文件,這種狀況下,inode信息也是不會改變的

總結

  • vim編輯是產生了一個新的文件,因此看到inode信息變化了,而echo僅僅只是對文件進行寫入。
  • 在vim編輯過程當中,會生成swp緩衝區文件,在進行vim編輯時時刻將內容保存進入swp,防止程序退出未保存
  • 產生後綴帶 ~ 的備份文件,這個是在對文件進行保存時產生,若是文件被正常保存則該文件會被當即刪除,正常狀況下是看不到這個文件
  • 若是文件other有write權限(chmod o+w xxx),則當進行vi寫入內容的時候文件inode不會改變。
  • 若是關閉vim備份,則inode信息也不會改變
相關文章
相關標籤/搜索