lsof介绍

2012年12月24日 | 分类: 生活点滴, 网络性能 | 标签:

linux系统中一切皆是文件,因此通过lsof相当于可以列出系统中的所有资源,包括套接字,目录,设备等的使用情况。

lsof默认输出格式,需要root权限才能查看特定文件信息:

[kongjian@v132172.sqa.cm4 ~]$ sudo lsof|more
COMMAND PID USER   FD      TYPE  DEVICE   SIZE    NODE     NAME
init 1     root  cwd       DIR  202,2      4096          2 /
init 1     root  mem       REG  202,2    144776    1507395 /lib64/ld-2.5.so
init 1     root  mem       REG  202,2   1722328    1507468 /lib64/libc-2.5.so
init 1     root  mem       REG  202,2     23360    1507550 /lib64/libdl-2.5.so
……

每一行是一个文件的使用情况,各列的含义如下:
COMMAND:进程的名称
PID:进程标识符
USER:进程所有者
FD:文件描述符,应用程序通过文件描述符识别该文件。如cwd、txt等
TYPE:文件类型,如DIR、REG等
DEVICE:指定磁盘的名称
SIZE:文件的大小
NODE:索引节点(文件在磁盘上的标识)
NAME:打开文件的确切名称

一些常用的命令

  • lsof -u like: 列出用户like打开的文件, 可指定多个用户, 默认是OR的关系;
  • lsof -c access: 列出名称以access开头的进程打开的文件, 可指定多个;
  • lsof -c /^t.*r$/ : 列出名称以t开头, r结尾的进程打开的文件;
  • lsof -p 12345: 列出进程号为12345的进程打开的文件, 可指定多个;
  • lsof /var/log/message : 列出打开/var/log/message文件的进程, 可指明多个文件;
  • lsof . : 列出打开当前目录的进程;
  • lsof +D . : 递归地列出当前目录中被打开的文件, 当然也可以lsof | grep `pwd`;
  • lsof -i : 列出打开的套接字;
  • lsof -i tcp : 列出打开的tcp套接字;
  • lsof -i :80: 列出打开80端口的进程;
  • lsof -i :ssh : 列出打开22端口的进程;
  • lsof -i tcp:80: 列出打开80号tcp端口的进程;
  • lsof -U : 列出打开Unix域套接字的进程;
  • lsof -d 0-2 : 列出在0到2文件描述符上打开文件的进程;
  • lsof -d mem : 列出打开映射文件的进程;
  • lsof -d txt : 列出打开的可执行文件.
  • lsof -a: 上述功能性选项可以组合使用, 但默认采用OR逻辑列出, -a选项令lsof使用AND逻辑;
  • lsof -t: 只列出进程号, 可以借此得到特定的进程列表, 以方便对这些进程的自动处理, 比如kill `lsof -t -i :1234`会杀死所有打开1234的进程;
  • lsof -r [seconds]: -r选项可以让lsof以一定的时间间隔连续执行, 在监视文件/进程时会非常实用.

特殊的一些场景
有时候我们发现删除了一个文件,但是空间没有释放出来,这是因为有进程还在使用该文件,因此文件不能够释放。需要通过lsof filename找到该文件被哪些进程使用,然后kill掉这些进程,空间才会真正释放出来。
利用这个特性,也可以恢复一些误删的日志文件,找到进程的pid,然后通过/proc/pid/fd中的文件描述符来恢复文件。
比如,对于文件/var/log/message:

[kongjian@v132172.sqa.cm4 modules]$ sudo lsof /var/log/messages
COMMAND    PID USER   FD   TYPE DEVICE    SIZE  NODE NAME
syslogd   1207 root    2w   REG  202,2 1369738 66574 /var/log/messages

可以看到有个进程打开了这个文件,pid分别是1207,文件描述符是2
于是我们可以通过/proc来查看该文件:

[kongjian@v132172.sqa.cm4 modules]$ sudo tail -f /proc/1207/fd/2
Dec 24 14:57:23 v132172 snmpd[1264]: Received SNMP packet(s) from UDP: [172.23.152.86]:57182
Dec 24 14:57:23 v132172 snmpd[1264]: Connection from UDP: [172.23.152.86]:34300
Dec 24 14:57:23 v132172 snmpd[1264]: Received SNMP packet(s) from UDP: [172.23.152.86]:34300
Dec 24 14:57:23 v132172 snmpd[1264]: Connection from UDP: [172.23.152.86]:60864

如果该文件被删除了,也可以通过/proc/fid/fd/恢复:

[root@v132172.sqa.cm4 log]# rm messages
[root@v132172.sqa.cm4 log]# cat /proc/1207/fd/2 > /var/log/messages

注意,这样恢复后,该进程对文件的操作会失效,需要重新加载。

本文的评论功能被关闭了.