本來今天不準備開電腦了,太睏了,想睡覺,然而一哥們兒簡訊都發過來了,要問個問題,於是還是開啟了電腦,沒想到是乙個很有代表性的問題,順便也牽扯了前些天我的工作中的乙個bug,值得記錄下來。問題如下:
linux下,乙個可執行檔案exe1正在執行中,rm –f可以將其刪除,mv可以將其移除,mv $other exe1也可以將其替換,但是cp $other exe1則顯示檔案忙,求解。
這實際上並不是乙個真正的問題,因為只要你的基礎知識紮實,這個問題顯然很簡單,原因只有乙個,那就是linux檔案基於引用計數。現在問題是這些個命令如何來操作乙個檔案的引用計數。下面的討論都是基於獨佔開啟的模式。
如果乙個檔案已經被開啟,那麼它的引用計數會增加1,如果呼叫了rm,實際上底層只是unlink了一下,也就是說將它的引用計數減少1,這樣雖然你在介面上(命令列或者gui)看不到它了,但是它被開啟時的計數還在,只有當它被關閉的時候,引用計數變為0,才徹底刪除它。
再說mv命令,它實際上只是乙個原始檔的rename而已,如果mv的目標本來就存在,那麼在目標上執行乙個類似rm的效果,也就是unlink一下,結合引用計數的理論,目標檔案如果已經被開啟,那麼當關閉的時候將不復存在,如果本來就沒有被開啟,那麼mv的時候,目標直接被刪除,因為unlink之後,它的引用計數變成了0。
最後看一下cp命令,cp的話並不觸動原始檔和目標檔案元資料本身(時間戳除外),它只是開啟原始檔和目標檔案,在原始檔上執行read,然後將結果write到目標檔案,實質上是乙個io操作,對於可執行檔案,是獨佔開啟的,並不允許寫入,因此會出錯。
這裡就不再列出核心原始碼了,可以自行參考系統呼叫的實現而加深理解,不過最好別乾巴巴的看,還是結合strace以及objdump比較好,要知道是怎麼以及什麼時候呼叫的,以及呼叫引數是什麼,否則就和八股文沒區別了。那麼這和我工作中的bug有什麼關係呢?這個bug源於openvpn的日誌記錄,並且配置了日誌回滾,回滾配置檔案關鍵字段如下:
size 4m
missingok
rotate 9
compress
delaycompress
create 644 xx xx
…
結果當日誌回滾成了vpn.log.1之後,這個vpn.log.1依然繼續被寫入。這個原因正是rename造成的。在logrotate的man頁面中,有乙個copytruncate配置,其含義就是不進行rename,而只是copy,然後將原來的檔案truncate,加入這個就可以了。
千萬不要小看這些很簡單的命令,真正理解的人並不多,即使真正的理解,出現問題,能真正對應到原理也不多,很簡單的東西如果能徹底做到透徹的理解並且活用,再往深入學習才是有意義的。
Linux中檔案執行中的鎖定的怪現象
本來今天不準備開電腦了,太睏了,想睡覺,然而一哥們兒簡訊都發過來了,要問個問題,於是還是開啟了電腦,沒想到是乙個很有代表性的問題,順便也牽扯了前些天我的工作中的乙個bug,值得記錄下來。問題如下 linux下,乙個可執行檔案exe1正在執行中,rm f可以將其刪除,mv可以將其移除,mv other...
linux檔案中的中文亂碼問題
問題背景 centos7中的檔案路徑,檔名中的中文漢字都顯示正常,但是開啟某個txt檔案時裡面的中文是亂碼的。分析 系統編碼應該是utf 8的,但是系統裡的檔案是gbk編碼的,所以會亂碼。解決 在終端中使用命令 echo lang 或locale 顯示zh cn.utf 8 證明系統編碼是utf 8...
Linux中資料夾的讀 寫 執行許可權
總結就拿我建立的new資料夾為例,可以看到資料夾的許可權是755,我以我自己的名字登陸系統並建立的資料夾,所以我目前屬於user,具有讀 寫和執行許可權。去掉執行許可權 可以看到去掉執行許可權之後,資料夾根本無法進入,更不要提對資料夾的讀和寫操作了。所以資料夾的執行許可權對應是否可以cd到資料夾中。...