天天看点

进程与文件的关系--lsof

lsof命令

作用:

1.列出指定文件被哪些进程打开(此处的文件是广义上的文件,可以表示linux上的一切东西)

2.列出指定端口被哪些进程所占用

3.根据用户或组来查询进程

4.根据文件描述符来查找进程

5.根据字符串来过滤进程

6.遍历某个目录来查找进程

7.扩展:恢复误删除的文件

本文使用到的选项

-c:根据字符串来搜索进程

-p:列出指定进程号所打开的文件

-a:合并多个选项

-g:列出相应组的进程所打开的文件

+d:列出指定目录下所有文件的打开情况

-n:不将ip转换为hostname

-i:列出占用指定端口或协议的进程

本文拓展

怎样恢复删除的文件

选项及用法:

-c:根据字符串来搜索进程

用法:
lsof -c string # 列出以字符串string开头的命令所打开的文件
~]# lsof -c sys   ##列出以sys开头的进程,此输出结果已被省略
~]# lsof -c redis  ##列出包含redis的进程
COMMAND    PID  USER   FD      TYPE             DEVICE  SIZE/OFF     NODE NAME
redis-ser 4233 redis  cwd       DIR              253,0        22 38780782 /var/lib/redis
redis-ser 4233 redis  rtd       DIR              253,0       288       64 /
redis-ser 4233 redis  txt       REG              253,0    975208    83904 /usr/bin/redis-server
redis-ser 4233 redis  mem       REG              253,0 106070960 33797329 /usr/lib/locale/locale-archive
redis-ser 4233 redis  mem       REG              253,0   2173512 33797336 /usr/lib64/libc-2.17.so
redis-ser 4233 redis  mem       REG              253,0    144792 33797370 /usr/lib64/libpthread-2.17.so
redis-ser 4233 redis  mem       REG              253,0    212096 38780776 /usr/lib64/libjemalloc.so.1
redis-ser 4233 redis  mem       REG              253,0     19776 33797342 /usr/lib64/libdl-2.17.so
redis-ser 4233 redis  mem       REG              253,0   1139680 33797345 /usr/lib64/libm-2.17.so
redis-ser 4233 redis  mem       REG              253,0    164240 33797328 /usr/lib64/ld-2.17.so
redis-ser 4233 redis    0r      CHR                1,3       0t0     5999 /dev/null
redis-ser 4233 redis    1u     unix 0xffff880015f48800       0t0    27946 socket
redis-ser 4233 redis    2u     unix 0xffff880015f48800       0t0    27946 socket
redis-ser 4233 redis    3u  a_inode                0,9         0     5995 [eventpoll]
redis-ser 4233 redis    4u     IPv4              28618       0t0      TCP node1.xjwlearn.com:6379 (LISTEN)

>>从输出结果中我们可以查看到包含redis字符串的所有进程信息,包括进程号,用户,inode号以及打开的文件路径等
           

-p:列出指定进程号所打开的文件

用法:
lsof -p PID #列出进程号为PID的进程所打开的文件
lsof -p PID1,PID2,...,PIDn
~]# lsof -p 4233 ##根据上面的结果我们知道redis的进程号为4233,此方式与上面的结果是完全一样的
redis-ser 4233 redis  cwd       DIR              253,0        22 38780782 /var/lib/redis
redis-ser 4233 redis  rtd       DIR              253,0       288       64 /
redis-ser 4233 redis  txt       REG              253,0    975208    83904 /usr/bin/redis-server
redis-ser 4233 redis  mem       REG              253,0 106070960 33797329 /usr/lib/locale/locale-archive
redis-ser 4233 redis  mem       REG              253,0   2173512 33797336 /usr/lib64/libc-2.17.so
redis-ser 4233 redis  mem       REG              253,0    144792 33797370 /usr/lib64/libpthread-2.17.so
redis-ser 4233 redis  mem       REG              253,0    212096 38780776 /usr/lib64/libjemalloc.so.1
redis-ser 4233 redis  mem       REG              253,0     19776 33797342 /usr/lib64/libdl-2.17.so
redis-ser 4233 redis  mem       REG              253,0   1139680 33797345 /usr/lib64/libm-2.17.so
redis-ser 4233 redis  mem       REG              253,0    164240 33797328 /usr/lib64/ld-2.17.so
redis-ser 4233 redis    0r      CHR                1,3       0t0     5999 /dev/null
redis-ser 4233 redis    1u     unix 0xffff880015f48800       0t0    27946 socket
redis-ser 4233 redis    2u     unix 0xffff880015f48800       0t0    27946 socket
redis-ser 4233 redis    3u  a_inode                0,9         0     5995 [eventpoll]
redis-ser 4233 redis    4u     IPv4              28618       0t0      TCP node1.xjwlearn.com:6379 (LISTEN)
           

-a:合并多个选项

注意:-a的使用方式很简单,只需要在添加-a选项后陆续添加其他的几个选项即可

~]# lsof -a -c redis  -u redis -d mem ##列出包含字符串redis并且文件描述符为mem且用户为redis的进程所打开的文件
COMMAND    PID  USER  FD   TYPE DEVICE  SIZE/OFF     NODE NAME
redis-ser 4233 redis mem    REG  253,0 106070960 33797329 /usr/lib/locale/locale-archive
redis-ser 4233 redis mem    REG  253,0   2173512 33797336 /usr/lib64/libc-2.17.so
redis-ser 4233 redis mem    REG  253,0    144792 33797370 /usr/lib64/libpthread-2.17.so
redis-ser 4233 redis mem    REG  253,0    212096 38780776 /usr/lib64/libjemalloc.so.1
redis-ser 4233 redis mem    REG  253,0     19776 33797342 /usr/lib64/libdl-2.17.so
redis-ser 4233 redis mem    REG  253,0   1139680 33797345 /usr/lib64/libm-2.17.so
redis-ser 4233 redis mem    REG  253,0    164240 33797328 /usr/lib64/ld-2.17.so
           

-g:列出相应组的进程所打开的文件

用法:
lsof -g GID  ##列出组号为GID的进程所打开的文件
~]# lsof -g 1000 ##列出组号为1000的进程所打开的文件
           

+d:列出指定目录下所有文件的打开情况

用法:
lsof +d directory
~]# lsof +d /etc
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF       NODE NAME
systemd     1 root   11r   REG    0,3        0 4026532025 /proc/swaps
lsof    10698 root    3r   DIR    0,3        0          1 /proc
           

注意:+d选项只能列出当前目录下的文件,子目录下的文件是不会被列出的,如若需要遍历所有文件,可以使用+D选项

-n与-i的组合使用:

-n:不将ip转换为hostname

-i:列出占用指定端口或协议的进程

用法:
lsof -i:port:根据端口查询
lsof -i tcp 查询tcp连接
lsof -i udp 查询udp连接
lsof -i tcp:22 查询占用tcp22号端口的进程
[[email protected] fd]# lsof -i:22
COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
sshd    4231 root    3u  IPv4  28632      0t0  TCP *:ssh (LISTEN)
sshd    4231 root    4u  IPv6  28634      0t0  TCP *:ssh (LISTEN)
sshd    7875 root    3u  IPv4 108289      0t0  TCP node1.xjwlearn.com:ssh->192.168.99.1:62006 (ESTABLISHED)
[[email protected] fd]# lsof -n -i:22
COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
sshd    4231 root    3u  IPv4  28632      0t0  TCP *:ssh (LISTEN)
sshd    4231 root    4u  IPv6  28634      0t0  TCP *:ssh (LISTEN)
sshd    7875 root    3u  IPv4 108289      0t0  TCP 192.168.99.100:ssh->192.168.99.1:62006 (ESTABLISHED)
           

列出文件或目录被哪些进程所使用:

lsof filename
lsof directory
           

lsof恢复误删除的文件

场景描述:应用程序正在对输出日志到文件a.log,此时若执行rm -f a.log,则此文件在系统中是不存在的,不能通过常规的命令去查看文件信息和内容,但是数据还是存储在磁盘。此时由于应用进程没有释放此文件,所以可以通获取此文件的描述符来恢复文件

~]# lsof deleted.filename   ##可显示出PID,FD,NUMBER等参数,这些参数可唯一确定一个文件,前提是此文件正在被某个进程使用
~]# cat /proc/PID/fd/NUMBER > somefile  ##将已经删除的文件重定向到somefile中
           

继续阅读