lsof 是 linux 下的一个非常实用的系统级的监控、诊断工具。
它的意思是 List Open Files,很容易你就记住了它是 “ls + of”的组合~
它可以用来列出被各种进程打开的文件信息,记住:linux 下 “一切皆文件”,
包括但不限于 pipes, sockets, directories, devices, 等等。
因此,使用 lsof,你可以获取任何被打开文件的各种信息。
lsof打开的文件可以是:
1.普通文件
2.目录
3.网络文件系统的文件
4.字符或设备文件
5.(函数)共享库
6.管道,命名管道
7.符号链接
8.网络文件(例如:NFS file、网络socket,unix域名socket)
9.还有其它类型的文件,等等
只需输入 lsof 就可以生成大量的信息,因为 lsof 需要访问核心内存和各种文件,所以必须以 root 用户的身份运行它才能够充分地发挥其功能。
lsof 的示例输出:
root@ubuntu:~# lsof |more COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME init 1 root cwd DIR 8,1 4096 2 / init 1 root rtd DIR 8,1 4096 2 / init 1 root txt REG 8,1 167192 1048582 /sbin/init init 1 root mem REG 8,1 52120 398011 /lib/x86_64-linux-gnu/libnss_files-2.15.so init 1 root mem REG 8,1 47680 393442 /lib/x86_64-linux-gnu/libnss_nis-2.15.so init 1 root mem REG 8,1 97248 398020 /lib/x86_64-linux-gnu/libnsl-2.15.so init 1 root mem REG 8,1 35680 398021 /lib/x86_64-linux-gnu/libnss_compat-2.15.so
每行显示一个打开的文件,若不指定条件默认将显示所有进程打开的所有文件。
lsof输出各列信息的意义如下:
COMMAND:进程的名称
PID:进程标识符
PPID:父进程标识符(需要指定-R参数)
USER:进程所有者
PGID:进程所属组(需要指定-R参数)
FD:文件描述符,应用程序通过文件描述符识别该文件。如cwd、txt等
(1)cwd:表示current work dirctory,即:应用程序的当前工作目录,这是该应用程序启动的目录,除非它本身对这个目录进行更改 (2)txt :该类型的文件是程序代码,如应用程序二进制文件本身或共享库,如上列表中显示的 /sbin/init 程序 (3)lnn:library references (AIX); (4)er:FD information error (see NAME column); (5)jld:jail directory (FreeBSD); (6)ltx:shared library text (code and data); (7)mxx :hex memory-mapped type number xx. (8)m86:DOS Merge mapped file; (9)mem:memory-mapped file; (10)mmap:memory-mapped device; (11)pd:parent directory; (12)rtd:root directory; (13)tr:kernel trace file (OpenBSD); (14)v86 VP/ix mapped file; (15)0:表示标准输出 (16)1:表示标准输入 (17)2:表示标准错误
一般在标准输出、标准错误、标准输入后还跟着文件状态模式:r、w、u等
(1)u:表示该文件被打开并处于读取/写入模式 (2)r:表示该文件被打开并处于只读模式 (3)w:表示该文件被打开并处于 (4)空格:表示该文件的状态模式为unknow,且没有锁定 (5)-:表示该文件的状态模式为unknow,且被锁定
同时在文件状态模式后面,还跟着相关的锁
(1)N:for a Solaris NFS lock of unknown type; (2)r:for read lock on part of the file; (3)R:for a read lock on the entire file; (4)w:for a write lock on part of the file;(文件的部分写锁) (5)W:for a write lock on the entire file;(整个文件的写锁) (6)u:for a read and write lock of any length; (7)U:for a lock of unknown type; (8)x:for an SCO OpenServer Xenix lock on part of the file; (9)X:for an SCO OpenServer Xenix lock on the entire file; (10)space:if there is no lock.
TYPE:文件类型,如DIR、REG等
常见的文件类型
(1)DIR:表示目录 (2)CHR:表示字符类型 (3)BLK:块设备类型 (4)UNIX: UNIX 域套接字 (5)FIFO:先进先出 (FIFO) 队列 (6)IPv4:网际协议 (IP) 套接字
DEVICE:指定磁盘的名称
SIZE:文件的大小
NODE:索引节点(文件在磁盘上的标识)
NAME:打开文件的确切名称
备注:
初始打开每个应用程序时,都具有三个文件描述符,从 0 到 2,分别表示标准输入、输出和错误流。所以大多数应用程序所打开的文件的 FD 都是从 3 开始。
2、lsof 常用用法
lsof语法格式是:
lsof [options] filename
lsof abc.txt
显示开启文件
abc.txt
的进程
lsof -c abc显示
abc
进程现在打开的文件
lsof -c -p 1234列出进程号为
1234
的进程所打开的文件
lsof -g gid显示归属
gid
的进程情况
lsof +d /usr/local/显示目录下被进程开启的文件
lsof +D /usr/local/同上,但是会搜索目录下的目录,时间较长
lsof -d 4显示使用
fd
为
4
的进程
lsof -i用以显示符合条件的进程情况
lsof -i[46] [protocol][@hostname|hostaddr][:service|port]
46 --> IPv4 or IPv6
protocol --> TCP or UDP
hostname --> Internet host name
hostaddr --> IPv4地址
service --> /etc/service中的
service name (
可以不止一个
)
port -->端口号
(
可以不止一个
)
2.1 监控打开的文件、设备
查看文件、设备被哪些进程占用
root@ubuntu:~# lsof /dev/tty1 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME getty 1114 root 0u CHR 4,1 0t0 5875 /dev/tty1 getty 1114 root 1u CHR 4,1 0t0 5875 /dev/tty1
2.2 监控文件系统
指定目录、挂载点,可以看到有哪些进程打开了其下的文件:
root@ubuntu:~# lsof /run/ COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME systemd-u 393 root 5u REG 0,16 8 9564 /run/udev/queue.bin cron 883 root 3u REG 0,16 4 9340 /run/crond.pid vmtoolsd 1132 root 4w REG 0,16 5 10481 /run/vmtoolsd.pid sshd 1354 ssp 7w FIFO 0,16 0t0 11159 /run/systemd/sessions/1.ref 。。。。。。。。
这在 umount 某个文件系统失败时非常有用(通常会报该 FS is busy)。
列出某个目录(挂载点 如 /home 也行)下被打开的文件:
lsof +d /usr/local/
显示目录下被进程开启的文件
lsof +D /usr/local/ 同上,但是会搜索目录下的目录,时间较长
root@ubuntu:~# lsof +D /var/log/ COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME init 1 root 11w REG 8,1 293 527702 /var/log/upstart/systemd-logind.log rsyslogd 568 syslog 1w REG 8,1 500562 527477 /var/log/syslog mysqld 934 mysql 1w REG 8,1 9311 525582 /var/log/mysql/error.log nginx 1026 www-data 5w REG 8,1 6213 525610 /var/log/nginx/error.log 。。。。
列出被指定进程名打开的文件:
lsof -c abc
显示
abc
进程现在打开的文件
root@ubuntu:~# lsof -c ssh -c init COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME init 1 root cwd DIR 8,1 4096 2 / sshd 861 root cwd DIR 8,1 4096 2 / 。。。。。。。。
2.3 监控进程
指定进程号,可以查看该进程打开的文件:
root@ubuntu:~# ps -ef |grep nginx root 1022 1 0 14:19 ? 00:00:00 nginx: master process /usr/sbin/nginx www-data 1023 1022 0 14:19 ? 00:00:00 nginx: worker process www-data 1024 1022 0 14:19 ? 00:00:00 nginx: worker process root@ubuntu:~# lsof -p 1022 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME nginx 1022 root cwd DIR 8,1 4096 2 / nginx 1022 root rtd DIR 8,1 4096 2 / nginx 1022 root txt REG 8,1 873176 924436 /usr/sbin/nginx nginx 1022 root mem REG 8,1 47712 399039 /lib/x86_64-linux-gnu/libnss_files-2.19.so 。。。。。。
当你想要杀掉某个用户所有打开的文件、设备,你可以这样:.
kill -9 `lsof -t -u nginx`
此处 -t 的作用是单独的列出 进程 id 这一列。-u 为制定用户
关于杀死进程的 4 种方式,请参考:
http://www.thegeekstuff.com/2009/12/4-ways-to-kill-a-process-kill-killall-pkill-xkill/
2.4 监控网络
查看指定端口有哪些进程在使用(lsof -i 列出所有的打开的网络连接):
root@ubuntu:~# lsof -i :22 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME sshd 861 root 3u IPv4 9400 0t0 TCP *:ssh (LISTEN) sshd 1335 root 3u IPv4 11111 0t0 TCP 10.18.98.61:ssh->10.18.96.34:59622 (ESTABLISHED)
列出被某个进程打开所有的网络文件:
root@ubuntu:~# lsof -i -a -p 1022 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME nginx 1022 root 7u IPv4 9501 0t0 TCP *:http (LISTEN) nginx 1022 root 8u IPv6 9502 0t0 TCP *:http (LISTEN) 或者 root@ubuntu:~# lsof -i -a -c nginx COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME nginx 1022 root 7u IPv4 9501 0t0 TCP *:http (LISTEN) nginx 1023 www-data 7u IPv4 9501 0t0 TCP *:http (LISTEN)
-c选项限定只列出以nginx开头的进程打开的文件
-a参数可以将多个选项的组合条件由或变为与 (and)
列出所有 tcp、udp 连接:
root@ubuntu:~# lsof -i tcp COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME sshd 861 root 3u IPv4 9400 0t0 TCP *:ssh (LISTEN) mysqld 934 mysql 10u IPv4 10600 0t0 TCP localhost:mysql (LISTEN) root@ubuntu:~# lsof -i udp COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME dhclient 714 root 6u IPv4 9073 0t0 UDP *:bootpc dhclient 714 root 20u IPv4 8993 0t0 UDP *:28931 dhclient 714 root 21u IPv6 8994 0t0 UDP *:5872
列出所有 NFS 文件:
root@ubuntu:~# lsof -N -u ssp �Ca
-N 列出所有NFS(网络文件系统)文件 (-N就对应NFS)
查看指定网口有哪些进程在使用:(@)
root@ubuntu:~# lsof -i @10.18.98.61 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME sshd 1335 root 3u IPv4 11111 0t0 TCP 10.18.98.61:ssh->10.18.96.34:59622 (ESTABLISHED) sshd 1354 ssp 3u IPv4 11111 0t0 TCP 10.18.98.61:ssh->10.18.96.34:59622 (ESTABLISHED)
3、更多使用技巧
3.1 监控用��
查看指定用�舸蚩�的文件(lsof -u ^ssp 可以排除某用户):
root@ubuntu:~# lsof -u ssp COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME sshd 1354 ssp cwd DIR 8,1 4096 2 / sshd 1354 ssp rtd DIR 8,1 4096 2 / sshd 1354 ssp txt REG 8,1 766784 930638 /usr/sbin/sshd sshd 1354 ssp DEL REG 0,4 11142 /dev/zero
3.2 监控应用程序
查看指定程序打开的文件:
-c选项限定只列出以nginx开头的进程打开的文件
root@ubuntu:~# lsof -c nginx (也可以 ng ngin 等等) COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME nginx 1022 root cwd DIR 8,1 4096 2 / nginx 1022 root rtd DIR 8,1 4096 2 / nginx 1022 root txt REG 8,1 873176 924436 /usr/sbin/nginx nginx 1022 root mem REG 8,1 97296 399048 /lib/x86_64-linux-gnu/libnsl-2.19.so
4、命令模式技巧
4.1 组合逻辑查询条件
只有多个查询条件都满足, 用 "-a" 参数,默认是 -o 。
root@ubuntu:~# lsof -a -u ssp -c ssh COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME sshd 1354 ssp cwd DIR 8,1 4096 2 / sshd 1354 ssp rtd DIR 8,1 4096 2 / sshd 1354 ssp txt REG 8,1 766784 930638 /usr/sbin/sshd sshd 1354 ssp DEL REG 0,4 11142 /dev/zero sshd 1354 ssp mem REG 8,1 14464 393516 /lib/x86_64-linux-gnu/security/pam_env.so
4.2 lsof 命令的重复执行模式:
基于给定的参数延时多少秒重复执行 lsof
+r 表示 当没有文件被打开的时候,repeat mode 将自行结束。
-r 表示 不管文件是否存在或者被打开,它都将执行,直到你中断它。
每个循环的输出使用 ‘=======’ 做分隔符,你也可以用 ‘-r’ | ‘+r’ 指定延时时间。
root@ubuntu:~# lsof -u ssp -c nginx -a -r1 (1秒循环一次,知道用户自己中断) ======= ======= root@ubuntu:~# lsof -u ssp -c nginx -a +r1 (1秒循环一次,如果没有输出的话就结束)
5、最后的技巧
关于磁盘空间告警 df -h --max=1 与 du -hx --max=1 显示不一致的问题,
最常见的的还是下面这种情况:
lsof|grep -i delete
看看被删除的文件:有些删了文件,但是进程没 reload,那些空间还是占用的,你可以理解为类似 windows 下的进程句柄没释放的概念吧~ 只是 windows 下如果有文件被进程使用,你一般是删不掉的,而 linux 虽然不做删除限制,但却要等到进程使用完文件才能完全释放,以防止进程奔溃,这是操作系统对资源的管理差异吧~
例如 nginx 会有很多临时文件占用了 /tmp 目录,删掉后,依然占用着空间,
此时你可以:
pkill -9 nginx && /etc/init.d/nginx restart
6、refer:
使用 lsof 查找打开的文件
http://www.ibm.com/developerworks/cn/aix/library/au-lsof.html
15 Linux lsof Command Examples (Identify Open Files)
http://www.thegeekstuff.com/2012/08/lsof-command-examples/
实用的系统工具之 lsof
http://www.ylinux.org/forum/t/276
原文地址:http://www.ylinux.org/forum/t/276