天天看點

linux lsof指令學習

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的功能是非常非常的強大。

後面如果有新的應用,會再分享出來;如果有任何問題,非常歡迎提出來讨論,謝謝。

繼續閱讀