lsof(list open files)是一个列出当前系统打开文件的工具。在linux环境下,任何事物都以文件的形式存在,经过文件不只仅能够访问常规数据,还能够访问网络链接和硬件。因此如传输控制协议 (TCP) 和用户数据报协议 (UDP) 套接字等,系统在后台都为该应用程序分配了一个文件描述符,不管这个文件的本质如何,该文件描述符为应用程序与基础操做系统之间的交互提供了通用接口。由于应用程序打开文件的描述符列表提供了大量关于这个应用程序自己的信息,所以经过lsof工具可以查看这个列表对系统监测以及排错将是颇有帮助的。 linux
注:Redhat系和Ubuntu系可分别用yum和apt-get来安装
centos
#yum install lsof
ubuntu
#apt-get install lsof
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME init 1 root cwd DIR 3,3 1024 2 / init 1 root rtd DIR 3,3 1024 2 / init 1 root txt REG 3,3 38432 1763452 /sbin/init init 1 root mem REG 3,3 106114 1091620 /lib/libdl-2.6.so init 1 root mem REG 3,3 7560696 1091614 /lib/libc-2.6.so init 1 root mem REG 3,3 79460 1091669 /lib/libselinux.so.1 init 1 root mem REG 3,3 223280 1091668 /lib/libsepol.so.1 init 1 root mem REG 3,3 564136 1091607 /lib/ld-2.6.so init 1 root 10u FIFO 0,15 1309 /dev/initctl在终端下输入lsof便可显示系统打开的文件,由于 lsof 须要访问核心内存和各类文件,因此必须以 root 用户的身份运行它才可以充分地发挥其功能。
COMMAND:进程的名称 PID:进程标识符 USER:进程全部者 FD:文件描述符,应用程序经过文件描述符识别该文件。如cwd、txt等 TYPE:文件类型,如DIR、REG等 DEVICE:指定磁盘的名称 SIZE:文件的大小 NODE:索引节点(文件在磁盘上的标识) NAME:打开文件的确切名称其中FD 列中的文件描述符cwd 值表示应用程序的当前工做目录,这是该应用程序启动的目录,除非它自己对这个目录进行更改。
lsof [options] filename
lsof filename 显示打开指定文件的全部进程 lsof -a 表示两个参数都必须知足时才显示结果 lsof -c string 显示COMMAND列中包含指定字符的进程全部打开的文件 lsof -u username 显示所属user进程打开的文件 lsof -g gid 显示归属gid的进程状况 lsof +d /DIR/ 显示目录下被进程打开的文件 lsof +D /DIR/ 同上,可是会搜索目录下的全部目录,时间相对较长 lsof -d FD 显示指定文件描述符的进程 lsof -n 不将IP转换为hostname,缺省是不加上-n参数 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 --> 端口号 (能够不仅一个)例如: 查看22端口如今运行的状况
# lsof -i :22 COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME sshd 1409 root 3u IPv6 5678 TCP *:ssh (LISTEN)查看所属root用户进程所打开的文件类型为txt的文件:
# lsof -a -u root -d txt COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME init 1 root txt REG 3,3 38432 1763452 /sbin/init mingetty 1632 root txt REG 3,3 14366 1763337 /sbin/mingetty mingetty 1633 root txt REG 3,3 14366 1763337 /sbin/mingetty mingetty 1634 root txt REG 3,3 14366 1763337 /sbin/mingetty mingetty 1635 root txt REG 3,3 14366 1763337 /sbin/mingetty mingetty 1636 root txt REG 3,3 14366 1763337 /sbin/mingetty mingetty 1637 root txt REG 3,3 14366 1763337 /sbin/mingetty kdm 1638 root txt REG 3,3 132548 1428194 /usr/bin/kdm X 1670 root txt REG 3,3 1716396 1428336 /usr/bin/Xorg kdm 1671 root txt REG 3,3 132548 1428194 /usr/bin/kdm startkde 2427 root txt REG 3,3 645408 1544195 /bin/bash ... ...
# lsof /GTES11/ COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME bash 4208 root cwd DIR 3,1 4096 2 /GTES11/ vim 4230 root cwd DIR 3,1 4096 2 /GTES11/在这个示例中,用户root正在其/GTES11目录中进行一些操做。一个 bash是实例正在运行,而且它当前的目录为/GTES11,另外一个则显示的是vim正在编辑/GTES11下的文件。要成功地卸载/GTES11,应该在通知用户以确保状况正常以后,停止这些进程。 这个示例说明了应用程序的当前工做目录很是重要,由于它仍保持着文件资源,而且能够防止文件系统被卸载。这就是为何大部分守护进程(后台进程)将它们的目录更改成根目录、或服务特定的目录(如 sendmail 示例中的 /var/spool/mqueue)的缘由,以免该守护进程阻止卸载不相关的文件系统。
# lsof |grep /var/log/messages syslogd 1283 root 2w REG 3,3 5381017 1773647 /var/log/messages (deleted)从上面的信息能够看到 PID 1283(syslogd)打开文件的文件描述符为 2。同时还能够看到/var/log/messages已经标记被删除了。所以咱们能够在 /proc/1283/fd/2 (fd下的每一个以数字命名的文件表示进程对应的文件描述符)中查看相应的信息,以下:
# head -n 10 /proc/1283/fd/2 Aug 4 13:50:15 holmes86 syslogd 1.4.1: restart. Aug 4 13:50:15 holmes86 kernel: klogd 1.4.1, log source = /proc/kmsg started. Aug 4 13:50:15 holmes86 kernel: Linux version 2.6.22.1-8 (root@everestbuilder.linux-ren.org) (gcc version 4.2.0) #1 SMP Wed Jul 18 11:18:32 EDT 2007 Aug 4 13:50:15 holmes86 kernel: BIOS-provided physical RAM map: Aug 4 13:50:15 holmes86 kernel: BIOS-e820: 0000000000000000 - 000000000009f000 (usable) Aug 4 13:50:15 holmes86 kernel: BIOS-e820: 000000000009f000 - 00000000000a0000 (reserved) Aug 4 13:50:15 holmes86 kernel: BIOS-e820: 0000000000100000 - 000000001f7d3800 (usable) Aug 4 13:50:15 holmes86 kernel: BIOS-e820: 000000001f7d3800 - 0000000020000000 (reserved) Aug 4 13:50:15 holmes86 kernel: BIOS-e820: 00000000e0000000 - 00000000f0007000 (reserved) Aug 4 13:50:15 holmes86 kernel: BIOS-e820: 00000000f0008000 - 00000000f000c000 (reserved)从上面的信息能够看出,查看 /proc/8663/fd/15 就能够获得所要恢复的数据。若是能够经过文件描述符查看相应的数据,那么就可使用 I/O 重定向将其复制到文件中,如:
cat /proc/1283/fd/2 > /var/log/messages对于许多应用程序,尤为是日志文件和数据库,这种恢复删除文件的方法很是有用。