主页

索引

模块索引

搜索页面

lsof命令

lsof 的常见用途之一是帮助我们找出在指定的 IP 地址或者端口上打开套接字的进程,而 netstat 则告诉我们 IP 地址和端口使用的情况,以及各个 TCP 连接的状态。

说明:

lsof是系统管理/安全的尤伯工具。
将这个工具称之为lsof真实名副其实,因为它是指“列出打开文件(lists openfiles)”
而有一点要切记,在Unix中一切(包括网络套接口)都是文件

lsof也是有着最多开关的Linux/Unix命令之一。
它有许多选项支持使用-和+前缀

关键选项

当你给它传递选项时,默认行为是对结果进行“或”运算:

因此,如果你正是用-i来拉出一个端口列表,同时又用-p来拉出一个进程列表,
那么默认情况下你会获得两者的结果。

下面的一些其它东西需要牢记:

默认 : 没有选项,lsof列出活跃进程的所有打开文件
组合 : 可以将选项组合到一起,如-abc,但要当心哪些选项需要参数
-a : 结果进行“与”运算(而不是“或”)
-l : 在输出显示用户ID而不是用户名
-h : 获得帮助
-t : 仅获取进程ID
-U : 获取UNIX套接口地址
-F : 格式化输出结果,用于其它命令。可以通过多种方式格式化,如-F pcfn(用于进程id、命令名、文件描述符、文件名,并以空终止)

lsof各列信息:

COMMAND:进程的名称
PID:进程标识符
PPID:父进程标识符(需要指定-R参数)
USER:进程所有者
PGID:进程所属组
FD:文件描述符,应用程序通过文件描述符识别该文件。如cwd、txt等:
TYPE:文件类型,如DIR、REG等,常见的文件类型:
DEVICE:指定磁盘的名称
SIZE:文件的大小
NODE:索引节点(文件在磁盘上的标识)
NAME:打开文件的确切名称

获取网络信息

使用-i显示所有连接:

语法: lsof -i[46] [protocol][@hostname|hostaddr][:service|port]
-i<条件> 列出符合条件的进程。(4、6、协议、:端口、 @ip)

实例:

$ lsof  -i
COMMAND  PID USER   FD   TYPE DEVICE SIZE NODE NAME
dhcpcd 6061 root 4u  IPv4  4510 UDP *:bootpc
sshd  7703 root 3u  IPv6  6499 TCP *:ssh  (LISTEN)
sshd  7892 root 3u  IPv6  6757 TCP 10.10.1.5:ssh->192.168.1.5:49901  (ESTABLISHED)

使用-i 6仅获取IPv6流量:

$ lsof  -i 6

仅显示TCP连接:

$ lsof  -i TCP
COMMAND  PID USER   FD   TYPE DEVICE SIZE NODE NAME
sshd  7703 root 3u  IPv6  6499 TCP *:ssh  (LISTEN)
sshd  7892 root 3u  IPv6  6757 TCP 10.10.1.5:ssh->192.168.1.5:49901  (ESTABLISHED)

使用-i:port来显示与指定端口相关的网络信息:

$ lsof  -i :22
$ lsof -i :smtp
$ lsof -i udp:53

//使用@host来显示指定到指定主机的连接
$ lsof  -i@172.16.12.5

//使用@host:port显示基于主机与端口的连接:
$ lsof  -i@172.16.12.5:22

找出指定类型端口:

// 监听端口
$ lsof  -i -sTCP:LISTEN
or
$ lsof  -i |  grep  -i LISTEN

// 已建立的连接:
$ lsof  -i -sTCP:ESTABLISHED
or
$ lsof  -i |  grep  -i ESTABLISHED

用户信息

  • 你也可以获取各种用户的信息,以及它们在系统上正干着的事情,包括它们的网络活动、对文件的操作等。

使用-u显示指定用户打开了什么:

$ lsof  -u gordon
-- snipped --
Dock  155 gordon  txt REG 14,2  2798436  823208  /usr/lib/libicucore.A.dylib
Dock  155 gordon  txt REG 14,2  1580212  823126  /usr/lib/libobjc.A.dylib
Dock  155 gordon  txt REG 14,2  2934184  823498  /usr/lib/libstdc++.6.0.4.dylib
Dock  155 gordon  txt REG 14,2  132008  823505  /usr/lib/libgcc_s.1.dylib
Dock  155 gordon  txt REG 14,2  212160  823214  /usr/lib/libauto.dylib
-- snipped --

使用-u user来显示除指定用户以外的其它所有用户所做的事情:

$ lsof  -u ^daniel
$ lsof -g gid 显示归属 gid 的进程情况

杀死指定用户所做的一切事情:

$ kill  -9  `lsof -t -u daniel`

命令和进程

  • 可以查看指定程序或进程由什么启动,这通常会很有用,而你可以使用lsof通过名称或进程ID过滤来完成这个任务。

使用-c查看指定的命令正在使用的文件和网络连接:

$ lsof  -c syslog-ng
COMMAND    PID USER   FD   TYPE     DEVICE    SIZE       NODE NAME
syslog-ng 7547 root  cwd    DIR 3,3  4096  2  /
syslog-ng 7547 root  rtd    DIR 3,3  4096  2  /
syslog-ng 7547 root  txt    REG 3,3  113524  1064970  /usr/sbin/syslog-ng
-- snipped --

使用-p查看指定进程ID已打开的内容:

$ lsof  -p 10075

-t选项只返回PID:

$ lsof  -t -c Mail

文件和目录

  • 通过查看指定文件或目录,你可以看到系统上所有正与其交互的资源——包括用户、进程等。

显示与指定目录交互的所有一切:

$ lsof  /var/log/messages/
COMMAND    PID USER   FD   TYPE DEVICE   SIZE   NODE NAME
syslog-ng 7547 root 4w REG 3,3  217309  834024  /var/log/messages

显示与指定文件交互的所有一切:

$ lsof  /home/daniel/firewall_whitelist.txt

递归:

$ lsof +d /DIR/ 显示目录下被进程打开的文件
    没有「+d选项」的话,似乎就不列出当前路径下被打印的文件了

$ lsof +D /DIR/ 同上,但是会搜索目录下的所有目录,时间相对较长

$ lsof -d FD 显示指定文件描述符的进程

实例:
// 递归查找某个目录中所有打开的文件
lsof +D /usr/lib

// 递归查找某个目录中所有打开的文件
lsof +D /usr/lib
lsof | grep '/usr/lib'     // 这个反应快

高级用法

  • 与tcpdump类似,当你开始组合查询时,它就显示了它强大的功能。

显示daniel连接到1.1.1.1所做的一切:

$ lsof  -u daniel -i @1.1.1.1

同时使用-t和-c选项以给进程发送 HUP 信号:

$ kill  -HUP `lsof -t -c sshd`

lsof +L1显示所有打开的链接数小于1的文件:

$ lsof  +L1

显示某个端口范围的打开的连接:

$ lsof  -i @fw.google.com:2150=2180

实操

恢复被删除的文件

原理:

当进程打开了某个文件时,只要该进程保持打开该文件,即使将其删除,它依然存在于磁盘中。
当文件删除时,进程并不知道文件已经被删除,它仍然可以向打开该文件时提供给它的文件描述符进行读取和写入。
除了该进程之外,这个文件是不可见的,因为已经删除了其相应的目录索引节点。

在/proc 目录下,其中包含了反映内核和进程树的各种文件。
/proc目录挂载的是在内存中所映射的一块区域,所以这些文件和目录并不存在于磁盘中,
因此当我们对这些文件进行读取和写入时,实际上是在从内存中获取相关信息。

大多数与 lsof 相关的信息都存储于以进程的 PID 命名的目录中,即 /proc/1234 中包含的是 PID 为 1234 的进程的信息。
每个进程目录中存在着各种文件,它们可以使得应用程序简单地了解进程的内存空间、文件描述符列表、
    指向磁盘上的文件的符号链接和其他系统信息。
lsof 程序使用该信息和其他关于内核内部状态的信息来产生其输出。
所以lsof 可以显示进程的文件描述符和相关的文件名等信息。

也就是我们通过访问进程的文件描述符可以找到该文件的相关信息。
当系统中的某个文件被意外地删除了,只要这个时候系统中还有进程正在访问该文件,
    那么我们就可以通过 lsof 从 /proc 目录下恢复该文件的内容。

实例:

恢复一个被删除的文件 test_recover

初始状态:

$ ls
test_recover test_recover2
$ less test_recover
goodfile
it is very good!!
it is used to test how to recover a deleted file with lsof.

删除文件 test_recover:

$ rm test_recover
说明: 我们已经将文件删除,但是由于 less 还在运行,所以这个文件虽然我们看不见了
  但是 less 不知道它删除了, less 还是可以对文件进行读写的,也就是说这个文件的数据实际还存在于磁盘上

查看删除的文件的信息:

$ lsof |grep test_recover
less 22197 quietheart 4r REG  8,8  87  1837925 /home/quietheart/test/lsof_test/test_recover (deleted)
说明: 通过 lsof 我们可以看到被删除的文件的信息

根据删除文件的信息恢复删除的文件:

$ cd /proc/22197/fd
$ ls
0  1  2  3  4
$ cat 4
goodfile
it is very good!!
it is used to test how to recover a deleted file with lsof.

列说明

FD列说明:

  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列说明:

(1)DIR:表示目录
(2)CHR:表示字符类型
(3)BLK:块设备类型
(4)UNIX: UNIX 域套接字
(5)FIFO:先进先出 (FIFO) 队列
(6)IPv4:网际协议 (IP) 套接字

实例

查看到底是谁打开了这个文件:

$ lsof /var/run/docker.sock

查看使用指定端口的进程:

$ lsof -i :8080

参考

主页

索引

模块索引

搜索页面