1)查看對某個文件的使用情況
?
?
?
-------------------------------------------------------
?
root@troy:/# lsof -w /etc/passwd
?
?
?
COMMAND? PID USER?? FD?? TYPE DEVICE SIZE/OFF??? NODE NAME
?
python? 2340 troy?? 10r?? REG??? 8,1???? 1804 2886346 /etc/passwd
?
-------------------------------------------------------
?
注:-w參數(shù)表示不打印警告信息.
?
lsof程序會打開/proc/PID/fd/目錄找到對映的文件句柄,再通過stat系統(tǒng)調(diào)用得到文件的詳細信息.
?
同時還會利用fdinfo目錄下的文件句柄得到打開文件時的狀態(tài).
?
例如:
?
?
?
1.1)創(chuàng)建程序test.c,本程序在/tmp/目錄下以O(shè)_WRONLY(只寫)和O_SYNC(同步)方式打開temp文件.
?
-------------------------------------------------------
?
root@troy:/tmp# more test.c
?
#include <unistd.h>
?
#include <sys/types.h>
?
#include <sys/stat.h>
?
#include <fcntl.h>
?
?
?
int main ()
?
{
?
??????? int fd;
?
??????? fd = open("/tmp/temp", O_WRONLY|O_SYNC);
?
??????? lseek(fd, 80L, SEEK_SET);
?
??????? sleep(100);
?
??????? close(fd);
?
?
?
??????? return 0;
?
}
?
?
?
root@troy:/tmp# gcc test.c -o testfd
?
root@troy:/tmp# ./testfd &
?
-------------------------------------------------------
?
?
?
1.2)觀察testfd程序打開的文件/tmp/temp
?
-------------------------------------------------------
?
cat /proc/$(lsof -w /tmp/temp|awk '/testfd/{print $2}')/fdinfo/3
?
pos: 80
?
flags: 0110001
?
-------------------------------------------------------
?
我們看到程序輸出pos和flags兩組數(shù)據(jù),pos字段表示被打開文件的當前讀寫位置,flags表示以文件方式打開該文件.
?
pos為80表示從文件起始位置移動80個字節(jié)的位置.
?
flags為0110001中的xxxxxx1表示以只寫方式打開文件,如果是只讀則為xxxxxx0,如果可讀可寫則為xxxxxx2,
?
其中的xx1xxxx表示以同步方式(O_SYNC)打開文件,如果改用以O(shè)_ASYNC方式打開文件,則為xx2xxxx,
?
如果同時指定了O_SYNC和O_ASYNC兩種方式打開文件,結(jié)果則為xx3xxxx.
?
如果我們增加了O_APPEND方式打開文件,結(jié)果則為xxx2xxx.
?
如果我們增加了O_NONBLOCK方式打開文件,結(jié)果則為xxx4xxx.
?
如果同時指定了O_APPEND和NONBLOCK兩種方式,結(jié)果則為xxx6xxx.
?
最后指明一下O_ASYNC用于打開終端和socket文件,默認產(chǎn)生SIGIO信號.
?
而O_NONBLOCK表示不阻塞打開的文件,只用于FIFO的管道文件中.
?
?
?
?
?
2)查看對某個目錄的使用情況
?
?
?
我們先執(zhí)行上個試驗的程序.
?
?
?
-------------------------------------------------------
?
root@troy:~# /tmp/testfd &
?
[1] 17021
?
?
?
root@troy:~# lsof +d /tmp/
?
COMMAND?? PID USER?? FD?? TYPE???????????? DEVICE SIZE/OFF?? NODE NAME
?
gedit??? 2531 troy??? 7u? unix 0xffff880029a49b00????? 0t0? 17106 /tmp/gedit.troy.917415843
?
testfd? 17021 root? txt??? REG??????????????? 8,1???? 8617 262475 /tmp/testfd
?
testfd? 17021 root??? 3w?? REG??????????????? 8,1??????? 0 262412 /tmp/temp
?
bash??? 3926? troy? cwd??? DIR??????????????? 8,1???? 4096 262149 /tmp
?
bash??? 4001? troy? cwd??? DIR??????????????? 8,1???? 4096 262149 /tmp
?
-------------------------------------------------------
?
?
?
如果不加參數(shù)+d呢?這里我們只看到了用戶的當前使用目錄,如下:
?
?
?
-------------------------------------------------------
?
root@troy:~# lsof -w /tmp
?
COMMAND? PID USER?? FD?? TYPE DEVICE SIZE/OFF?? NODE NAME
?
bash??? 3926 troy? cwd??? DIR??? 8,1???? 4096 262149 /tmp
?
bash??? 4001 troy? cwd??? DIR??? 8,1???? 4096 262149 /tmp
?
-------------------------------------------------------
?
?
?
有什么區(qū)別嗎?
?
加+d參數(shù)的情況下,lsof會遍列所有的進程,以及進程下所有的fd,fdinfo,cwd,root,exec,maps,以查找被程序占用中的目錄.
?
而不加參數(shù)+d的情況下,lsof只會遍列所有進程的cwd,cwd是用戶當前目錄的軟鏈接.如下:
?
?
?
-------------------------------------------------------
?
root@troy:~# ls -l /proc/3926/cwd
?
lrwxrwxrwx 1 troy troy 0 2011-02-09 19:23 /proc/3926/cwd -> /tmp
?
-------------------------------------------------------
?
?
?
?
?
?
?
3)查看某個進程的使用情況
?
-------------------------------------------------------
?
troy@troy:/proc/23294$ lsof -p 23294
?
COMMAND?? PID USER?? FD?? TYPE? DEVICE SIZE/OFF??? NODE NAME
?
ssh???? 23294 troy? cwd??? DIR???? 8,1???? 4096? 262149 /tmp
?
ssh???? 23294 troy? rtd??? DIR???? 8,1???? 4096?????? 2 /
?
ssh???? 23294 troy? txt??? REG???? 8,1?? 339712 1058082 /usr/bin/ssh
?
ssh???? 23294 troy? mem??? REG???? 8,1??? 51712? 787472 /lib/libnss_files-2.11.1.so
?
ssh???? 23294 troy? mem??? REG???? 8,1??? 43552? 787456 /lib/libnss_nis-2.11.1.so
?
ssh???? 23294 troy? mem??? REG???? 8,1??? 97256? 787430 /lib/libnsl-2.11.1.so
?
ssh???? 23294 troy? mem??? REG???? 8,1??? 35712? 787454 /lib/libnss_compat-2.11.1.so
?
ssh???? 23294 troy? mem??? REG???? 8,1?? 135745? 787466 /lib/libpthread-2.11.1.so
?
ssh???? 23294 troy? mem??? REG???? 8,1??? 10224? 787804 /lib/libkeyutils-1.2.so
?
ssh???? 23294 troy? mem??? REG???? 8,1??? 31168 1050775 /usr/lib/libkrb5support.so.0.1
?
ssh???? 23294 troy? mem??? REG???? 8,1??? 14584? 798518 /lib/libcom_err.so.2.1
?
ssh???? 23294 troy? mem??? REG???? 8,1?? 154048 1050756 /usr/lib/libk5crypto.so.3.1
?
ssh???? 23294 troy? mem??? REG???? 8,1?? 803192 1050769 /usr/lib/libkrb5.so.3.3
?
ssh???? 23294 troy? mem??? REG???? 8,1??? 14696? 795838 /lib/libdl-2.11.1.so
?
ssh???? 23294 troy? mem??? REG???? 8,1? 1572232? 787469 /lib/libc-2.11.1.so
?
ssh???? 23294 troy? mem??? REG???? 8,1?? 213784 1050761 /usr/lib/libgssapi_krb5.so.2.2
?
ssh???? 23294 troy? mem??? REG???? 8,1??? 93000? 787444 /lib/libresolv-2.11.1.so
?
ssh???? 23294 troy? mem??? REG???? 8,1??? 92752? 786985 /lib/libz.so.1.2.3.3
?
ssh???? 23294 troy? mem??? REG???? 8,1? 1622304? 796093 /lib/libcrypto.so.0.9.8
?
ssh???? 23294 troy? mem??? REG???? 8,1?? 136936? 787431 /lib/ld-2.11.1.so
?
ssh???? 23294 troy??? 0u?? CHR? 136,20????? 0t0????? 23 /dev/pts/20
?
ssh???? 23294 troy??? 1u?? CHR? 136,20????? 0t0????? 23 /dev/pts/20
?
ssh???? 23294 troy??? 2u?? CHR? 136,20????? 0t0????? 23 /dev/pts/20
?
ssh???? 23294 troy??? 3u? IPv4 1603924????? 0t0???? TCP troy.local:41879->10.1.1.7:ssh (ESTABLISHED)
?
ssh???? 23294 troy??? 4w? FIFO???? 0,8????? 0t0 1603904 pipe
?
ssh???? 23294 troy??? 5u?? CHR? 136,19????? 0t0????? 22 /dev/pts/19
?
ssh???? 23294 troy??? 6r?? CHR???? 5,0????? 0t0??? 1129 /dev/tty
?
ssh???? 23294 troy??? 7u?? CHR? 136,21????? 0t0????? 24 /dev/pts/21
?
ssh???? 23294 troy??? 8u?? CHR? 136,20????? 0t0????? 23 /dev/pts/20
?
ssh???? 23294 troy??? 9u?? CHR? 136,20????? 0t0????? 23 /dev/pts/20
?
ssh???? 23294 troy?? 10u?? CHR? 136,20????? 0t0????? 23 /dev/pts/20
?
-------------------------------------------------------
?
?
?
lsof程序會跟據(jù)用戶指定的PID,遍列/proc/目錄找到該PID,在/proc/PID目錄下依次打開stat,maps,fd,fdinfo.
?
stat文件包含了當前進程的信息.
?
當前進程的stat如下:
?
23294 (ssh) S 23291 23294 23294 34837 23294 4202496 836 0 0 0 8 10 0 0 20 0 1 0 29282141 39632896 658 18446744073709551615 140114439372800 140114439700540 140733214155456 140733214149016 140114423930835 0 0 4096 136331271 18446744071580239593 0 0 17 1 0 0 0 0 0
?
?
?
maps文件包含映像的文件:
?
當前進程的maps如下:
?
7f6eecf42000-7f6eecf4e000 r-xp 00000000 08:01 787472???????????????????? /lib/libnss_files-2.11.1.so
?
7f6eecf4e000-7f6eed14d000 ---p 0000c000 08:01 787472???????????????????? /lib/libnss_files-2.11.1.so
?
7f6eed14d000-7f6eed14e000 r--p 0000b000 08:01 787472???????????????????? /lib/libnss_files-2.11.1.so
?
7f6eed14e000-7f6eed14f000 rw-p 0000c000 08:01 787472???????????????????? /lib/libnss_files-2.11.1.so
?
7f6eed14f000-7f6eed159000 r-xp 00000000 08:01 787456???????????????????? /lib/libnss_nis-2.11.1.so
?
7f6eed159000-7f6eed358000 ---p 0000a000 08:01 787456???????????????????? /lib/libnss_nis-2.11.1.so
?
7f6eed358000-7f6eed359000 r--p 00009000 08:01 787456???????????????????? /lib/libnss_nis-2.11.1.so
?
7f6eed359000-7f6eed35a000 rw-p 0000a000 08:01 787456???????????????????? /lib/libnss_nis-2.11.1.so
?
7f6eed35a000-7f6eed371000 r-xp 00000000 08:01 787430???????????????????? /lib/libnsl-2.11.1.so
?
7f6eed371000-7f6eed570000 ---p 00017000 08:01 787430???????????????????? /lib/libnsl-2.11.1.so
?
7f6eed570000-7f6eed571000 r--p 00016000 08:01 787430???????????????????? /lib/libnsl-2.11.1.so
?
7f6eed571000-7f6eed572000 rw-p 00017000 08:01 787430???????????????????? /lib/libnsl-2.11.1.so
?
后省略.
?
這里用pmap 23294也可以找到加載的文件與虛擬地址的對映.
?
?
?
fd,fdinfo我們已經(jīng)分析過了,當lsof找到/proc/23294/3時,發(fā)現(xiàn)是個socket文件,如下:
?
?
?
----------------------------------------------------
?
troy@troy:/proc/23294/fd$ ls -l
?
total 0
?
lrwx------ 1 troy troy 64 2011-02-11 02:47 0 -> /dev/pts/20
?
lrwx------ 1 troy troy 64 2011-02-11 02:47 1 -> /dev/pts/20
?
lrwx------ 1 troy troy 64 2011-02-11 02:47 10 -> /dev/pts/20
?
lrwx------ 1 troy troy 64 2011-02-11 01:07 2 -> /dev/pts/20
?
lrwx------ 1 troy troy 64 2011-02-11 02:47 3 -> socket:[1603924]
?
l-wx------ 1 troy troy 64 2011-02-11 02:47 4 -> pipe:[1603904]
?
lrwx------ 1 troy troy 64 2011-02-11 02:47 5 -> /dev/pts/19
?
lr-x------ 1 troy troy 64 2011-02-11 02:47 6 -> /dev/tty
?
lrwx------ 1 troy troy 64 2011-02-11 02:47 7 -> /dev/pts/21
?
lrwx------ 1 troy troy 64 2011-02-11 02:47 8 -> /dev/pts/20
?
lrwx------ 1 troy troy 64 2011-02-11 02:47 9 -> /dev/pts/20
?
----------------------------------------------------
?
?
?
此時會依次打開以下的文件,對網(wǎng)絡(luò)套字接進行分析,各文件作用如下:
?
/proc/net/raw ---->原始套接字
?
/proc/net/unix ---->UNIX套接字
?
/proc/net/sockstat ---->當前套接字的使用情況
?
/proc/net/tcp ---->TCP套接字
?
/proc/net/udp ---->UDP套接字
?
/proc/net/udplite --->UDP無線通訊套接字
?
?
?
在/proc/net/tcp會找到對映的inode,socket:[1603924]的inode為1603924,而tcp中sl為12的一行正是這個socket服務(wù).如下:
?
----------------------------------------------------
?
more /proc/net/tcp
?
? sl? local_address rem_address?? st tx_queue rx_queue tr tm->when retrnsmt?? uid? timeout inode???????????????????????????????????????????????????
?
?? 0: 00000000:0087 00000000:0000 0A 00000000:00000000 00:00000000 00000000???? 0??????? 0 8984 1 ffff8800677d1380 300 0 0 2 -1????????????????????
?
?? 1: 00000000:0369 00000000:0000 0A 00000000:00000000 00:00000000 00000000???? 0??????? 0 8575 1 ffff8800677d0d00 300 0 0 2 -1????????????????????
?
?? 2: 00000000:0050 00000000:0000 0A 00000000:00000000 00:00000000 00000000???? 0??????? 0 8673 1 ffff880068c51a00 300 0 0 2 -1????????????????????
?
?? 3: 00000000:1770 00000000:0000 0A 00000000:00000000 00:00000000 00000000???? 0??????? 0 5350 1 ffff880068c50680 300 0 0 2 -1????????????????????
?
?? 4: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000???? 0??????? 0 4315 1 ffff880068c50000 300 0 0 2 -1????????????????????
?
?? 5: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000???? 0??????? 0 25571 1 ffff88001a06c780 300 0 0 2 -1???????????????????
?
?? 6: 00000000:0BB8 00000000:0000 0A 00000000:00000000 00:00000000 00000000???? 0??????? 0 7881 1 ffff8800677d0680 300 0 0 2 -1????????????????????
?
?? 7: 00000000:BD59 00000000:0000 0A 00000000:00000000 00:00000000 00000000???? 0??????? 0 8986 1 ffff880068c52080 300 0 0 2 -1????????????????????
?
?? 8: 0100007F:0019 00000000:0000 0A 00000000:00000000 00:00000000 00000000???? 0??????? 0 6304 1 ffff880068c50d00 300 0 0 2 -1????????????????????
?
?? 9: 4506010A:D6E9 0701010A:0016 01 00000000:00000000 02:00028405 00000000? 1502??????? 0 1603452 2 ffff880057896180 22 4 8 5 -1??????????????????
?
? 10: 4506010A:89A5 0701010A:0016 01 00000000:00000000 02:00091EFF 00000000? 1502??????? 0 1672803 2 ffff88001a068680 25 4 18 4 -1??????????????????
?
? 11: 4506010A:872E 0701010A:0016 01 00000000:00000000 02:0004B77C 00000000? 1502??????? 0 1177942 2 ffff880057893a80 125 4 0 3 2??????????????????
?
? 12: 4506010A:A397 0701010A:0016 01 00000000:00000000 02:0004D6A6 00000000? 1502??????? 0 1603924 2 ffff880057894e00 23 4 0 5 -1??????????????????
?
? 13: 4506010A:BD31 0701010A:0016 01 00000000:00000000 02:000139A5 00000000? 1502??????? 0 1345002 2 ffff880057897500 22 4 0 5 -1??????????????????
?
? 14: 4506010A:8F21 0701010A:0016 01 00000000:00000000 02:000192BE 00000000? 1502??????? 0 1351794 2 ffff880057896800 25 4 12 4 -1?????????????????
?
? 15: 4506010A:8AD1 0701010A:0016 01 00000000:00000000 02:00094915 00000000? 1502??????? 0 1447912 2 ffff880068c55b00 21 4 14 4 -1
?
----------------------------------------------------
?
其中l(wèi)ocal_address代表本地的IP和端口
?
4506010A(本地地址)的45轉(zhuǎn)化為十進制是69,06轉(zhuǎn)化為十制制是6,01轉(zhuǎn)化為十進制是1,0A轉(zhuǎn)化為十進制是10,倒過來也就是10.1.1.69,是本地地址.
?
A397(本地端口)轉(zhuǎn)化為十進制是41879,也就是本地端口
?
rem_address代表遠程IP和端口
?
0701010A(遠程地址):10.1.1.7
?
0016(遠程端口)22
?
其它參數(shù)都是內(nèi)核調(diào)試時使用
?
uid就是用戶的UID
?
?
?
?
?
?
?
4)顯示所屬user進程打開的文件
?
?
?
----------------------------------------------------
?
root@troy:/proc/2554# lsof -u test -w
?
COMMAND? PID USER?? FD?? TYPE???????????? DEVICE SIZE/OFF??? NODE NAME
?
su????? 2554 test? cwd??? DIR??????????????? 8,1???? 4096?????? 2 /
?
su????? 2554 test? rtd??? DIR??????????????? 8,1???? 4096?????? 2 /
?
su????? 2554 test? txt??? REG??????????????? 8,1??? 36864? 262185 /bin/su
?
su????? 2554 test? mem??? REG??????????????? 8,1??? 27024? 797476 /lib/libnss_lsass.so.2.0.0
?
su????? 2554 test? mem??? REG??????????????? 8,1??? 10272 1102794 /usr/lib/gconv/IBM850.so
?
su????? 2554 test? mem??? REG??????????????? 8,1??? 14392 1102782 /usr/lib/gconv/UTF-16.so
?
su????? 2554 test? mem??? REG??????????????? 8,1??? 43528? 795516 /lib/security/pam_gnome_keyring.so
?
su????? 2554 test? mem??? REG??????????????? 8,1?? 256768? 787477 /lib/libdbus-1.so.3.4.0
?
su????? 2554 test? mem??? REG??????????????? 8,1??? 14536 1052877 /usr/lib/libck-connector.so.0.0.0
?
su????? 2554 test? mem??? REG??????????????? 8,1??? 10360? 795488 /lib/security/pam_ck_connector.so
?
su????? 2554 test? mem??? REG??????????????? 8,1??? 14344? 787928 /lib/libgpg-error.so.0.4.0
?
su????? 2554 test? mem??? REG??????????????? 8,1?? 491000? 787918 /lib/libgcrypt.so.11.5.2
?
su????? 2554 test? mem??? REG??????????????? 8,1??? 92752? 786985 /lib/libz.so.1.2.3.3
?
su????? 2554 test? mem??? REG??????????????? 8,1??? 67896 1055840 /usr/lib/libtasn1.so.3.1.7
?
su????? 2554 test? mem??? REG??????????????? 8,1??? 10224? 787804 /lib/libkeyutils-1.2.so
?
su????? 2554 test? mem??? REG??????????????? 8,1??? 31168 1050775 /usr/lib/libkrb5support.so.0.1
?
su????? 2554 test? mem??? REG??????????????? 8,1??? 14584? 798518 /lib/libcom_err.so.2.1
?
以下略
?
----------------------------------------------------
?
?
?
通過strace,我們知道lsof通過stat系統(tǒng)調(diào)用得到這個進程的目錄owner,正是我們要找的用戶進程.
?
?
?
如下:
?
stat("/proc/2554/", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0
?
open("/proc/2554/stat", O_RDONLY)?????? = 4
?
read(4, "2554 (su) S 2533 2554 2533 34817"..., 4096) = 241
?
?
?
最后lsof通過調(diào)用cwd,root,fd,fdinfo,maps以及網(wǎng)絡(luò)套接字顯示輸出用戶進程所使用的文件.
?
?
?
?
?
?
?
5)顯示網(wǎng)絡(luò)服務(wù)
?
?
?
----------------------------------------------------
?
root@troy:~# lsof -i
?
COMMAND??? PID??????? USER?? FD?? TYPE DEVICE SIZE/OFF NODE NAME
?
smbd?????? 767??????? root?? 22u? IPv6?? 4410????? 0t0? TCP *:microsoft-ds (LISTEN)
?
smbd?????? 767??????? root?? 23u? IPv6?? 4412????? 0t0? TCP *:netbios-ssn (LISTEN)
?
sshd?????? 787??????? root??? 3u? IPv4?? 4227????? 0t0? TCP *:ssh (LISTEN)
?
sshd?????? 787??????? root??? 4u? IPv6?? 4229????? 0t0? TCP *:ssh (LISTEN)
?
avahi-dae? 809?????? avahi?? 13u? IPv4?? 4568????? 0t0? UDP *:mdns
?
avahi-dae? 809?????? avahi?? 14u? IPv4?? 4569????? 0t0? UDP *:50511
?
dhclient?? 883??????? root??? 5u? IPv4?? 4530????? 0t0? UDP *:bootpc
?
Xorg?????? 912??????? root??? 1u? IPv6?? 4705????? 0t0? TCP *:x11 (LISTEN)
?
Xorg?????? 912??????? root??? 3u? IPv4?? 4706????? 0t0? TCP *:x11 (LISTEN)
?
dcerpcd?? 1132??????? root?? 15u? IPv4?? 8845????? 0t0? TCP *:loc-srv (LISTEN)
?
dcerpcd?? 1132??????? root?? 16u? IPv4?? 8846????? 0t0? UDP *:loc-srv
?
eventlogd 1261??????? root?? 14u? IPv4?? 8850????? 0t0? TCP *:55846 (LISTEN)
?
exim4???? 1563 Debian-exim??? 3u? IPv4?? 6359????? 0t0? TCP localhost:smtp (LISTEN)
?
以下略
?
----------------------------------------------------
?
?
?
lsof通過遍列所有進程的所有文件句柄,找到網(wǎng)絡(luò)套接字,再通過/proc/net/下面的網(wǎng)絡(luò)信息得到具體的套接字信息.