淺談Linux下mv和cp命令的區別
阿新 • • 發佈:2019-02-09
我之前在專案中遇到一個很奇怪的問題,對於inotify監視一個檔案的時候,發現有些時候inotify有些時候會
“失效”。後來我就沒辦法,去監視檔案所在的目錄。看下面的,
#!/bin/bash
src=/tmp/test/test.txt # directory to monitor
/usr/local/bin/inotifywait -rmq -e modify $src | while read event
do
echo "hello"
done
奇怪的現象就是如果我 mv test.txt /tmp/test/test.txt 的時候,發現 inotify 竟然沒有除非,但是我無意中
發現 cp test.txt /tmp/test/test.txt 的時候,強制覆蓋了,發現 inotity 就觸發了。我這兩天上OS的時候,突
然間想到了原因。可能是 inode 節點的問題,看下面
上面注意 inode 節點的變化,cp 的時候是真正意義上的內容copy,對於 inode 節點卻是不會變化的
mv 的時候是把目標檔案直接刪除了(inode 刪除了),新的檔案其實已經不是以前的檔案了,只是名字
一樣而已。這樣就可以解釋 inotify 的“異常”了,mv 之後原檔案的 inode 節點都已經刪除了,inotify是跑
在記憶體裡面的,它依然在讀取之前的 inode 節點,但是已經刪除了,這導致了inotify掛了。
inode 是OS在磁碟上尋找檔案一個必不可少的,下面可以再來看個例子.
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <fcntl.h> int main(int argc, char const *argv[]) { /* code */ int fd = open("./1.txt",O_RDWR); char buff[256] = {'\0'}; if (fd < 0) { printf("error open file\n"); exit(1); } int i = 0; while(1) { sprintf(buff,"%d %s\n",i,"hello"); write(fd,buff,strlen(buff)+1); printf("%s\n",buff ); ++i; sleep(1); } close(fd); return 0; }
上面的程式就是向1.txt寫檔案,前提是 1.txt 是存在的,真正的原因就是沒有 inode 節點,也就沒有了對應
的磁碟檔案.現在假設有了 1.txt 這時候程式 1s 鍾寫一次檔案,我們 mv 1.txt 2.txt ,這時候會發現程式竟
然向 2.txt 裡面寫資料了,原因就是程式是在記憶體裡面,對於1.txt 的抽象就是檔案描述符號,write只認識它
,write 通過寫描述符,描述符去找相應的 inode 節點,然後寫磁碟.mv 了之後 inode 節點還是存在的,也
就是寫 2.txt 了.