1. lsof是什麼?
lsof是linux下面一個tool,用來列出目前系統中所打開的檔案,這些檔案包括
正規檔案、目錄、管道、字元裝置、塊裝置、unix socket等等。
2. 那lsof有什麼作用呢?
(1)你的程式有沒有出現過open檔案失敗的情況?那我們可以通過lsof來檢視系統中已經
open了多少檔案,會不會跟這有關系。
從以下的結果你可以看到系統預設的最大open files是1024個,是以如果你已經打開了
1024個檔案了,那就會open失敗了。
通常發生此問題的原因都是程式中調用了open,但是用完檔案之後卻沒有去close。
sh-# ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 2293
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 2293
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
我們做個試驗,故意将open files數目改為1,你會發現很多linux command已經無法運作了。
sh-# ulimit -n 1
sh-# ls
ls: error while loading shared libraries: librt.so.1: cannot open shared object file: Error 24
sh-# busybox which
busybox: error while loading shared libraries: libm.so.6: cannot open shared object file: Error 24
(2)從lsof的執行結果,我們也可以看到有哪些user正在使用目前的file system;
或者是目前file system中有哪些已經被打開的檔案。
sh-# umount /mnt/sda1/
umount: /mnt/usb/sda1: device is busy.
(In some cases useful info about processes that use
the device is found by lsof(8) or fuser(1))
當unmount一個file system失敗時,可以使用lsof來檢視你的file system是否仍然有正在open着的檔案。
sh-# ./lsof /mnt/sda1/
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
ooxx 537 root 46r REG 8,1 6 45 /mnt/sda1/test.txt
可以看到有一個test.txt是打開的,是以需要先close這個檔案再去unmount才能成功。
(3)有時候我們能夠使用lsof來恢複那些已經删除掉(比如說誤删)的檔案,為什麼能做到?
這是因為這些open的檔案在RAM中都有對應的映像,是以我們就可以用/proc這個特殊的
file system來恢複,具體步驟是:
a. 使用lsof查到哪個process打開了這個檔案,以及這個被打開檔案的file descriptor:
sh-3# ./lsof | grep test.txt
process_name 747 root 46r REG 8,1 6 45 /mnt/sda1/test.txt (deleted)
process_name 747 541 root 46r REG 8,1 6 45 /mnt/sda1/test.txt (deleted)
b. 接下來你會發現這果然就是你之前删掉的檔案的内容:
sh-# cat /proc/747/fd/46
dfdfd
c. 将這個誤删的檔案小心翼翼的存回去:
sh-3.2# cat /proc/537/fd/46 > /mnt/usb/sda1/restore.txt
sh-3.2# cat /mnt/usb/sda1/restore.txt
dfdfd
2013/09/13補充:
剛做了試驗來确認,如果檔案被open,再被delete,再被close之後就不能利用這種辦法來恢複delete的檔案了。
因為檔案被close了,該檔案對應的file descriptor被系統回收,是以在/proc/pid/fd/中就沒有對應檔案的
file descriptor了。是以,使用lsof也隻能去恢複那些被delete但是仍然是open的檔案。
以上是個人學習過程中的一些心得和應用,實際上lsof這個tool的功能是非常非常的強大。
後面如果有新的應用,會再分享出來;如果有任何問題,非常歡迎提出來讨論,謝謝。