lsof-显示系统打开的文件

荒凉一梦 提交于 2019-12-24 17:01:50

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

[root@CentOS7 ~]# lsof -h
lsof 4.87
 latest revision: ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/
 latest FAQ: ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/FAQ
 latest man page: ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/lsof_man
 usage: [-?abhKlnNoOPRtUvVX] [+|-c c] [+|-d s] [+D D] [+|-f[gG]] [+|-e s]
 [-F [f]] [-g [s]] [-i [i]] [+|-L [l]] [+m [m]] [+|-M] [-o [o]] [-p s]
[+|-r [t]] [-s [p:s]] [-S [t]] [-T [t]] [-u s] [+|-w] [-x [fl]] [--] [names]
Defaults in parentheses; comma-separated set (s) items; dash-separated ranges.
  -?|-h list help # 帮助
  -a AND selections (OR) # and 操作
  -b avoid kernel blocks # 避免系统阻塞
  -c c  cmd c ^c /c/[bix] # 显示出以字符或字符串c开头的命令程序,例如:lsof -csshd
  +c w  COMMAND width (9)    
  +d s  dir s files # 在文件夹s下搜寻,此参数不会继续深入搜寻此文件夹
  -d s  select by FD set # 此参数以file descriptor(FD)值显示结果,可以采用范围(1-3)或个别
  +D D  dir D tree *SLOW?* # 同+d,但是会以该文件为基础往下全部搜寻
  +|-e s  exempt s *RISKY* 
  -i select IPv[46] files # 选择ip协议文件
  -K list tasKs (threads) # 展示线程信息 
  -l list UID numbers # 展示用户ID而不是用户名
  -n no host names # 展示ip而不是hostname
  -N select NFS files        
  -o list file offset
  -O no overhead *RISKY*   
  -P no port names # 禁止把端口号转化成服务名展示
  -R list paRent PID
  -s list file size # 列出文件的大小,若该文件没有大小,则留下空白 
  -t terse listing  # 精简输出列表,默认只展示pid
  -T disable TCP/TPI info
  -U select Unix socket # 使用socket文件查找
  -v list version info  # 展示版本信息 
  -V verbose search
  +|-w  Warnings (+)       -X skip TCP&UDP* files     -Z Z  context [Z]
  -- end option scan     
  +f|-f  +filesystem or -file names     +|-f[gG] flaGs 
  -F [f] select fields; -F? for help  
  +|-L [l] list (+) suppress (-) link counts < l (0 = all; default = 0)
                                        +m [m] use|create mount supplement
  +|-M   portMap registration (-)       -o o   o 0t offset digits (8)
  -p s   exclude(^)|select PIDs # 指定进程ID
  -S [t] t second stat timeout (15)
  -T qs TCP/TPI Q,St (s) info
  -g [s] exclude(^)|select and print process group IDs # 显示进程所属的进程组
  -i i   select by IPv[46] address: [46][proto][@host|addr][:svc_list|port_list] # 列出符合条件的进程
  +|-r [t[m<fmt>]] repeat every t seconds (15);  + until no files, - forever.
       An optional suffix to t is m<fmt>; m must separate t from <fmt> and
      <fmt> is an strftime(3) format for the marker line.
  -s p:s  exclude(^)|select protocol (p = TCP|UDP) states by name(s).
  -u s   exclude(^)|select login|UID set s # 展示指定用户名或者用户ID
  -x [fl] cross over +d|+D File systems or symbolic Links
  names  select named files or files on named file systems
Anyone can list all files; /dev warnings disabled; kernel ID check disabled.

type列

DIR:表示目录。 
CHR:表示字符类型。 
BLK:块设备类型。 
UNIX: UNIX 域套接字。 
FIFO:先进先出 (FIFO) 队列。 
IPv4:网际协议 (IP) 套接字。 
DEVICE:指定磁盘的名称 
SIZE:文件的大小 
NODE:索引节点(文件在磁盘上的标识) 
NAME:打开文件的确切名称

例子

# -i 测试
[root@CentOS7 ~]# lsof -i @192.168.174.50:22
COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
sshd    2213 root    3u  IPv4  18815      0t0  TCP bogon:ssh->bogon:49381 (ESTABLISHED)
[root@CentOS7 ~]# lsof -i :22
COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
sshd    1088 root    3u  IPv4  17397      0t0  TCP *:ssh (LISTEN)
sshd    1088 root    4u  IPv6  17406      0t0  TCP *:ssh (LISTEN)
sshd    2213 root    3u  IPv4  18815      0t0  TCP bogon:ssh->bogon:49381 (ESTABLISHED)
[root@CentOS7 ~]# lsof -i 4tcp@192.168.174.50:22
COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
sshd    2213 root    3u  IPv4  18815      0t0  TCP bogon:ssh->bogon:49381 (ESTABLISHED)

# -u 测试
[root@CentOS7 ~]# lsof  -u dbus
COMMAND   PID USER   FD      TYPE             DEVICE SIZE/OFF     NODE NAME
dbus-daem 873 dbus  cwd       DIR              253,0     4096      128 /
dbus-daem 873 dbus  rtd       DIR              253,0     4096      128 /
dbus-daem 873 dbus  txt       REG              253,0   441176 34003067 /usr/bin/dbus-daemon
。。。。。。
dbus-daem 873 dbus   17u     unix 0xffff880039de5640      0t0    17663 /var/run/dbus/system_bus_socket

# -a 测试
[root@CentOS7 ~]# lsof -i :22 -a -u root -n
COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
sshd    1089 root    3u  IPv4  17358      0t0  TCP *:ssh (LISTEN)
sshd    1089 root    4u  IPv6  17372      0t0  TCP *:ssh (LISTEN)
sshd    2213 root    3u  IPv4  18739      0t0  TCP 192.168.174.50:ssh->192.168.174.1:56829 (ESTABLISHED)

# +d 测试
[root@CentOS7 ~]# lsof +d /dev/
COMMAND    PID    USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
systemd      1    root    0u   CHR                1,3      0t0 5817 /dev/null
systemd      1    root    1u   CHR                1,3      0t0 5817 /dev/null
systemd      1    root    2u   CHR                1,3      0t0 5817 /dev/null
systemd      1    root   25r   CHR             10,235      0t0 7735 /dev/autofs
......
sshd      2213    root   10u   CHR                5,2      0t0 7738 /dev/ptmx
sshd      2213    root   11u   CHR                5,2      0t0 7738 /dev/ptmx

# +d +D 区别
[root@CentOS7 ~]# lsof +D /dev/ | grep input
systemd-l  867    root   14u   CHR              13,64      0t0 7778 /dev/input/event0
[root@CentOS7 ~]# lsof +d /dev/ | grep input

# -p 测试
[root@CentOS7 ~]# lsof -i :22 -p 1089,2213 -a
COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
sshd    1089 root    3u  IPv4  17358      0t0  TCP *:ssh (LISTEN)
sshd    1089 root    4u  IPv6  17372      0t0  TCP *:ssh (LISTEN)
sshd    2213 root    3u  IPv4  18739      0t0  TCP bogon:ssh->bogon:56829 (ESTABLISHED)

恢复删除文件

当Linux计算机受到入侵时,常见的情况是日志文件被删除,以掩盖攻击者的踪迹。管理错误也可能导致意外删除重要的文件,比如在清理旧
日志时,意外地删除了数据库的活动事务日志。有时可以通过lsof来恢复这些文件。 

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

在/proc 目录下,其中包含了反映内核和进程树的各种文件。/proc目录挂载的是在内存中所映射的一块区域,所以这些文件和目录并不存在
于磁盘中,因此当我们对这些文件进行读取和写入时,实际上是在从内存中获取相关信息。大多数与 lsof 相关的信息都存储于以进程的 PID
命名的目录中,即 /proc/1234 中包含的是 PID 为 1234 的进程的信息。每个进程目录中存在着各种文件,它们可以使得应用程序简单地了解
进程的内存空间、文件描述符列表、指向磁盘上的文件的符号链接和其他系统信息。lsof 程序使用该信息和其他关于内核内部状态的信息来产
生其输出。所以lsof 可以显示进程的文件描述符和相关的文件名等信息。也就是我们通过访问进程的文件描述符可以找到该文件的相关信息。 

当系统中的某个文件被意外地删除了,只要这个时候系统中还有进程正在访问该文件,那么我们就可以通过lsof从/proc目录下恢复该文件的
内容。 假如由于误操作将/var/log/messages文件删除掉了,那么这时要将/var/log/messages文件恢复的方法如下: 

首先使用lsof来查看当前是否有进程打开/var/logmessages文件,如下:
# 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: L....太长省略
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

对于许多应用程序,尤其是日志文件和数据库,这种恢复删除文件的方法非常有用。
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!