lsof命令详解
lsof 是 List Open File 的缩写, 它主要⽤来获取被进程打开⽂件的信息,我们都知道,在Linux中,⼀切皆⽂件,lsof命令可以查看所有已经打开了的⽂件,⽐如:普通⽂件,⽬录,特殊的块⽂件,管道,socket套接字,设备,Unix域套接字等等。系统在后台都为该应⽤程序分配了⼀个⽂件描述符,⽆论这个⽂件的本质如何,该⽂件描述符为应⽤程序与基础操作系统之间的交互提供了通⽤接⼝。同时,它还可以结合 grep 以及 ps 命令进⾏更多的⾼级搜索
lsof 命令可显⽰系统打开的⽂件,因为 lsof 需要访问核⼼内存和各种⽂件,所以必须以 root ⽤户的⾝份运⾏它才能够充分地发挥其功能。
1.命令格式
lsof [参数][⽂件]
2.命令功能
⽤于查看你进程开打的⽂件,打开⽂件的进程,进程打开的端⼝(TCP、UDP)。回/恢复删除的⽂件。是⼗分⽅便的系统监视⼯具,因为 lsof 需要访问核⼼内存和各种⽂件,所以需要 root ⽤户执⾏。
lsof打开的⽂件可以是:
普通⽂件
⽬录
⽹络⽂件系统的⽂件
字符或设备⽂件
(函数)共享库
管道,命名管道
符号链接
⽹络⽂件(例如:NFS file、⽹络socket,unix域名socket)
还有其它类型的⽂件,等等
3.命令参数
[root@ito-yw-host ~]# 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) -b avoid kernel blocks
-c c cmd c ^c /c/[bix] +c w COMMAND width (9) +d s dir s files
-d s select by FD set +D D dir D tree *SLOW?* +|-e s exempt s *RISKY*
-
i select IPv[46] files -K list tasKs (threads) -l list UID numbers
-n no host names -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 -T disable TCP/TPI info
-U select Unix 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 -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
-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.
-a 列出打开⽂件存在的进程
-c<;进程名> 列出指定进程所打开的⽂件
-g 列出GID号进程详情
-d<⽂件号> 列出占⽤该⽂件号的进程
+d<⽬录> 列出⽬录下被打开的⽂件
+D<⽬录> 递归列出⽬录下被打开的⽂件
-n<⽬录> 列出使⽤NFS的⽂件
-i<;条件> 列出符合条件的进程。(4、6、协议、:端⼝、 )
-p<;进程号> 列出指定进程号所打开的⽂件
-
u 列出UID号进程详情
-h 显⽰帮助信息
-v 显⽰版本信息
4.安装
lsof 命令默认是没有安装的,⽽且它的使⽤需要有root权限或者赋予普通⽤于sudo权限, 使⽤以下命令安装
yum install -y lsof
5.输出解析
lsof 命令有很多可选参数,不带任何参数执⾏ lsof 命令会输出当前所有活跃进程打开的所有⽂件,由于lsof命令会输出很多信息,在⽰例中我们查看前10⾏,对输出字段进⾏解析
[root@centos-7.9 ~]# lsof | head
COMMAND PID TID USER FD TYPE DEVICE SIZE/OFF NODE NAME
systemd 1 root cwd DIR 253,0 4096 64 /
systemd 1 root rtd DIR 253,0 4096 64 /
systemd 1 root txt REG 253,0 1632736 67801506 /usr/lib/systemd/systemd
systemd 1 root mem REG 253,0 20064 33763358 /usr/lib64/libuuid.so.1.3.0
systemd 1 root mem REG 253,0 265576 34448764 /usr/lib64/libblkid.so.1.1.0
systemd 1 root mem REG 253,0 90248 33763451 /usr/lib64/libz.so.1.2.7
systemd 1 root mem REG 253,0 157424 33769169 /usr/lib64/liblzma.so.5.2.2
systemd 1 root mem REG 253,0 23968 33769162 /usr/lib64/libcap-ng.so.0.0.0
systemd 1 root mem REG 253,0 19896 33786740 /usr/lib64/libattr.so.1.1.0
输出结果中列 COMMAND 、PID、TID、USER 分别表⽰进程名、进程ID、线程ID、所属⽤户
第⼀列中 systemd 的进程 ID 是 1,它是系统的守护进程
列 FD 是⽂件描述符,下⾯是可能的类型以及说明
FD说明
cwd当前⽬录
txt txt⽂件
rtd root⽬录
mem内存映射⽂件
列 TYPE 是⽂件类型,下⾯是可能的值以及说明
TYPE说明
DIR⽬录
REG普通⽂件
CHR字符
a_inode Inode⽂件
FIFO管道或者socket⽂件
netlink⽹络
unknown未知
DEVICE 列表⽰设备ID
SIZE/OFF 列表⽰进程⼤⼩
NODE 列表⽰⽂件的Inode号
NAME 列表⽰路径或者链接
6、实例
(1)列出指定⽤户已打开的⽂件
使⽤ -u 选项可以列出指定⽤户已经打开的⽂件,该选项后⾯可以接多个⽤户名,每个⽤户名之间⽤空格隔开,表⽰列出所有指定⽤户已打开的所有⽂件[root@centos-7.9 ~]# lsof -u gdm,apache
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
php-fpm 1181 apache cwd DIR 253,0 4096 64 /
php-fpm 1181 apache rtd DIR 253,0 4096 64 /
php-fpm 1181 apache txt REG 253,0 4781848 103960545 /opt/rh/rh-php72/root/usr/sbin/php-fpm
php-fpm 1181 apache mem REG 253,0 70008 101418157 /usr/lib64/gconv/libGB.so
省略……
php-fpm 1181 apache 0u CHR 1,3 0t0 2052 /dev/null
php-fpm 1181 apache 1u CHR 1,3 0t0 2052 /dev/null
php-fpm 1181 apache 2u CHR 1,3 0t0 2052 /dev/null
php-fpm 1181 apache 9u unix 0xffff9fa3e5fa0880 0t0 12179700 /var/opt/rh/rh-php72/run/php-fpm/zabbix.sock
gnome-ses 2418 gdm cwd DIR 253,0 97 1444834 /var/lib/gdm
gnome-ses 2418 gdm rtd DIR 253,0 4096 64 /
gnome-ses 2418 gdm txt REG 253,0 298608 101780481 /usr/libexec/gnome-session-binary
省略……
上⾯的例⼦中,lsof -u gdm,apache 命令表⽰列出 dgm和apache ⽤户已经打开了的⽂件
如果要排除指定⽤户已经打开的⽂件,可以在⽤户名前加 ^ 符号,下⾯的命令会列出除 apache ⽤户外其他所有⽤户已打开了的⽂件
lsof -u ^apache | more
(2)出被删除依然打开的⽂件
在⼀些场景中,你可能会发现磁盘空间满了但不到占⽤空间的⽂件,这很有可能是某些⽂件虽被删除了,却没有释放磁盘空间,这种情况往往是有进程打开了该⽂件。那我们如何到这些删除的⽂件呢?可以结合 grep 命令出这种⽂件。lsof |grep deleted 可出系统所有的被打开且已删除的⽂件,你可以加上其他的选项以实现更精细查,如查mysql ⽤户打开并删除的⽂件 lsof -u mysql |grep deleted 。利⽤这种特性也可以实现删除⽂件的恢复,
[root@centos-7.9 ~]# lsof |grep deleted
abrt-watc 1398 root 4r REG 253,0 32461 100937591 /var/log/Xorg.0.log (deleted)
rsyslogd 1872 root 8w REG 253,0 5028953 104140086 /var/log/cron-20210314 (deleted)
rs:main 1872 1924 root 8w REG 253,0 5028953 104140086 /var/log/cron-20210314 (deleted)
rs:main 1872 1924 root 9w REG 253,0 118985294 104140092 /var/log/maillog-20210314 (deleted)
X 2301 root 4w REG 253,0 32461 100937591 /var/log/Xorg.0.log (deleted)
llvmpipe- 2301 2361 root 4w REG 253,0 32461 100937591 /var/log/Xorg.0.log (deleted)
mysqld 2378 mysql 5u REG 253,0 0 67913255 /tmp/ibBmtyYs (deleted)
利⽤这种特性也可以实现删除⽂件的恢复,打开 /var/log/cron-20210314 的进程 id 为1872 ,进⼊ /proc/1872/fd/ 就可以看到该进程打开的所有⽂件,已删除的⽂件在末尾会标注 “(deleted)”,8 是指向/var/log/cron-20210314的,⽤head 查看下⽂件查到内容是完好的,现在就很容易恢复了。
[root@centos-7.9 ~]# cd /proc/1872/fd/
[root@centos-7.9 fd]# ll
总⽤量 0
lr-x------ 1 root root 64 3⽉ 11 2021 0 -> /dev/null
lr-x------ 1 root root 64 3⽉ 11 2021 3 -> anon_inode:inotify
l-wx------ 1 root root 64 3⽉ 11 2021 4 -> /var/log/messages
省略……
l-wx------ 1 root root 64 3⽉ 11 2021 8 -> /var/log/cron-20210314 (deleted)
l-wx------ 1 root root 64 3⽉ 11 2021 9 -> /var/log/maillog-20210314 (deleted)
[root@centos-7.9 fd]# head 8
Mar 7 03:47:02 centos-7.9 run-parts(/etc/cron.daily)[11338]: finished logrotate
Mar 7 03:47:02 centos-7.9 run-parts(/etc/cron.daily)[11297]:
Mar 7 03:47:04 centos-7.9 run-parts(/etc/cron.daily)[11354]:
省略……
[root@centos-7.9 fd]#
(3)列出所有打开了的⽹络⽂件
[root@centos-7.9 ~]# lsof -i |head -15
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
rpcbind 1368 rpc 6u IPv4 13566 0t0 UDP *:sunrpc
rpcbind 1368 rpc 7u IPv4 13567 0t0 UDP *:connendp
rpcbind 1368 rpc 8u IPv4 13568 0t0 TCP *:sunrpc (LISTEN)
rpcbind 1368 rpc 9u IPv6 13569 0t0 UDP *:sunrpc
rpcbind 1368 rpc 10u IPv6 13570 0t0 UDP *:connendp
rpcbind 1368 rpc 11u IPv6 13571 0t0 TCP *:sunrpc (LISTEN)
avahi-dae 1373 avahi 12u IPv4 18700 0t0 UDP *:mdns
avahi-dae 1373 avahi 13u IPv4 18701 0t0 UDP *:52604
cupsd 1864 root 10u IPv6 121 0t0 TCP localhost:ipp (LISTEN)
cupsd 1864 root 11u IPv4 122 0t0 TCP localhost:ipp (LISTEN)
sshd 1866 root 3u IPv4 19927 0t0 TCP *:ssh (LISTEN)
sshd 1866 root 4u IPv6 19929 0t0 TCP *:ssh (LISTEN)
master 2217 root 13u IPv4 63727 0t0 TCP localhost:smtp (LISTEN)
master 2217 root 14u IPv6 63728 0t0 TCP localhost:smtp (LISTEN)
(4)列出所有 IPV4/6 ⽹络⽂件
列出所有已经打开了的 ipv4 ⽹络⽂件
[root@centos-7.9 ~]# lsof -i 4 |head
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
rpcbind 1368 rpc 6u IPv4 13566 0t0 UDP *:sunrpc
rpcbind 1368 rpc 7u IPv4 13567 0t0 UDP *:connendp
rpcbind 1368 rpc 8u IPv4 13568 0t0 TCP *:sunrpc (LISTEN)
avahi-dae 1373 avahi 12u IPv4 18700 0t0 UDP *:mdns
avahi-dae 1373 avahi 13u IPv4 18701 0t0 UDP *:52604
cupsd 1864 root 11u IPv4 122 0t0 TCP localhost:ipp (LISTEN)
sshd 1866 root 3u IPv4 19927 0t0 TCP *:ssh (LISTEN)
master 2217 root 13u IPv4 63727 0t0 TCP localhost:smtp (LISTEN)
zabbix_ag 3802 zabbix 4u IPv4 70087 0t0 TCP *:zabbix-agent (LISTEN)
所有已经打开了的 ipv6 ⽹络⽂件
[root@centos-7.9 ~]# lsof -i 6 |head
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
rpcbind 1368 rpc 9u IPv6 13569 0t0 UDP *:sunrpc
rpcbind 1368 rpc 10u IPv6 13570 0t0 UDP *:connendp
rpcbind 1368 rpc 11u IPv6 13571 0t0 TCP *:sunrpc (LISTEN)
cupsd 1864 root 10u IPv6 121 0t0 TCP localhost:ipp (LISTEN)
sshd 1866 root 4u IPv6 19929 0t0 TCP *:ssh (LISTEN)
master 2217 root 14u IPv6 63728 0t0 TCP localhost:smtp (LISTEN)
mysqld 2378 mysql 36u IPv6 39979 0t0 TCP *:mysql (LISTEN)
zabbix_ag 3802 zabbix 5u IPv6 70088 0t0 TCP *:zabbix-agent (LISTEN)
zabbix_ag 3804 zabbix 5u IPv6 70088 0t0 TCP *:zabbix-agent (LISTEN)
(5)列出在指定端⼝上打开的⽂件**
使⽤ lsof -i:端⼝号可以获得所有在指定端⼝号上打开的⽂件
[root@centos-7.9 ~]# lsof -i:22
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
sshd 1866 root 3u IPv4 19927 0t0 TCP *:ssh (LISTEN)
sshd 1866 root 4u IPv6 19929 0t0 TCP *:ssh (LISTEN)
sshd 37696 root 3u IPv4 617315159 0t0 TCP centos-7.9:ssh->10.200.4.33:60638 (ESTABLISHED)
上⾯例⼦列出了所有在22号端⼝上打开的⽂件,包括IPv4/IPv6监听和1个tcp连接
列出⽬前连接主机 localhost 上端⼝为:20,21,22,25,53,80相关的所有⽂件信息,且每隔3秒不断的执⾏lsof指令
命令:
lsof -i @localhost:20,21,22,25,53,80 -r 3
(6)列出使⽤了指定协议(TCP/UDP) 的⽂件
使⽤ lsof -i TCP/UDP 列出使⽤了TCP 或 UDP 协议的⽂件
[root@centos-7.9 ~]# lsof -ni TCP
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
rpcbind 1368 rpc 8u IPv4 13568 0t0 TCP *:sunrpc (LISTEN)
mysqld 2378 mysql 36u IPv6 39979 0t0 TCP *:mysql (LISTEN)
sshd 11956 root 3u IPv4 617470628 0t0 TCP 10.200.52.10:ssh->10.200.4.33:62917 (ESTABLISHED)
使⽤ lsof -i TCP:3306 列出使⽤了TCP 协议并且端⼝为3306的⽂件
[root@centos-7.9 ~]# lsof -ni TCP:2379
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
coredns 18408 root 7u IPv4 247062628 0t0 TCP 192.168.10.201:39484->192.168.10.201:2379 (ESTABLISHED) coredns 18408 root 8u IPv4 247149626 0t0 TCP 192.168.10.201:39486->192.168.10.201:2379 (ESTABLISHED) coredns 18408 root 9u IPv4 247079604 0t0 TCP 192.168.10.201:39488->192.168.10.201:2379 (ESTABLISHED) etcd 23441 etcd 6u IPv6 98156846 0t0 TCP *:2379 (LISTEN)
etcd 23441 etcd 11u IPv4 98156848 0t0 TCP 127.0.0.1:33226->127.0.0.1:2379 (ESTABLISHED)
etcd 23441 etcd 12u IPv6 98156849 0t0 TCP 127.0.0.1:2379->127.0.0.1:33226 (ESTABLISHED)
etcd 23441 etcd 13u IPv6 247086177 0t0 TCP 192.168.10.201:2379->192.168.10.201:39484 (ESTABLISHED) etcd 23441 etcd 14u IPv6 247086178 0t0 TCP 192.168.10.201:2379->192.168.10.201:39486 (ESTABLISHED)
etcd 23441 etcd 15u IPv6 247086180 0t0 TCP 192.168.10.201:2379->192.168.10.201:39488 (ESTABLISHED)
使⽤ lsof -i TCP:1-1024 列出使⽤了TCP协议并且端⼝范围为 1 到 1024 的⽂件
[root@centos-7.9 ~]# lsof -ni TCP:1-1024
列出谁在使⽤某个特定的udp端⼝,命令:
lsof -i udp:5500
Shell
或者:特定的tcp端⼝,命令:
lsof -i tcp:8081
(7)列出所有⽹络⽂件系统
命令:
lsof -N
(8)列出在特定⽬录打开的⽂件
lsof命令列出指定⽬录中的所有打开⽂件
+D 选项会列出⼀个⽬录和其⼦⽬录中打开的⽂件
[root@centos-7.9 ~]# lsof +D /home/mysql/lib/mysql
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
mysqld 2378 mysql cwd DIR 253,2 4096 268665313 /home/mysql/lib/mysql
mysqld 2378 mysql 3uW REG 253,2 50331648 268665315 /home/mysql/lib/mysql/ib_logfile0
mysqld 2378 mysql 4uW REG 253,2 18874368 268826238 /home/mysql/lib/mysql/zabbix/events.ibd
mysqld 2378 mysql 9uW REG 253,2 50331648 268665316 /home/mysql/lib/mysql/ib_logfile1
mysqld 2378 mysql 10uW REG 253,2 146800640 268665314 /home/mysql/lib/mysql/ibdata1
mysqld 2378 mysql 11uW REG 253,2 35001466880 268826226 /home/mysql/lib/mysql/zabbix/history_uint.ibd
略……
+d 选项只会列出当前⽬录下已打开的⽂件
[root@centos-7.9 ~]# lsof +d /home/mysql/lib/mysql
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
mysqld 2378 mysql cwd DIR 253,2 4096 268665313 /home/mysql/lib/mysql
mysqld 2378 mysql 3uW REG 253,2 50331648 268665315 /home/mysql/lib/mysql/ib_logfile0
mysqld 2378 mysql 9uW REG 253,2 50331648 268665316 /home/mysql/lib/mysql/ib_logfile1
mysqld 2378 mysql 10uW REG 253,2 146800640 268665314 /home/mysql/lib/mysql/ibdata1
mysqld 2378 mysql 19uW REG 253,2 79691776 268665280 /home/mysql/lib/mysql/ibtmp1
lsof 后也可以直接跟逻辑卷或磁盘
[root@centos-7.9 ~]# lsof /dev/mapper/centos-root
(9)列出指定进程ID打开的⽂件
进程ID是操作系统进程的唯⼀标识,如果想要知道某进程打开的⽂件可以使⽤ lsof -p PID命令查询
[root@centos-7.9 ~]# lsof -p 41927
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
nginx 41927 root cwd DIR 253,0 4096 64 /
nginx 41927 root rtd DIR 253,0 4096 64 /
nginx 41927 root txt REG 253,0 1215088 34272922 /usr/sbin/nginx
nginx 41927 root mem REG 253,0 27624 2489009 /usr/lib64/perl5/vendor_perl/auto/nginx/nginx.so
nginx 41927 root 7u IPv6 179578988 0t0 TCP *:webcache (LISTEN)
nginx 41927 root 8u unix 0xffff9fb1486c6e80 0t0 179580272 socket
nginx 41927 root 9u unix 0xffff9fb1486c6a40 0t0 179580273 socket
nginx 41927 root 10u unix 0xffff9fb1486c61c0 0t0 179580274 socket
上述命令中,-p 选项后⾯可以指定多个进程ID,每个进程ID之间⽤逗号分隔,如果想排除掉某个进程打开的⽂件,可以在该进程ID前⾯加上 ^符号lsof -p 1,2,3,^4
上述命令会列出进程1,进程2,进程3打开的所有⽂件,同时忽略进程4打开的⽂件
(10)列出某个程序进程所打开的⽂件信息
命令:
lsof -c mysql
Shell
说明:
-c 选项将会列出所有以mysql这个进程开头的程序的⽂件,其实你也可以写成 lsof | grep mysql, 但是第⼀种⽅法明显⽐第⼆种⽅法要少打⼏个字符了列出多个进程多个打开的⽂件信息
命令:
lsof -c mysql -c apache
(11)据⽂件描述列出对应的⽂件信息
命令:
lsof -d description(like 2)
Shell
例如:lsof -d txtoffset命令
例如:lsof -d 1
例如:lsof -d 2
说明:
0表⽰标准输⼊,1表⽰标准输出,2表⽰标准错误,从⽽可知:所以⼤多数应⽤程序所打开的⽂件的 FD 都是从 3 开始
根据⽂件描述范围列出⽂件信息
命令:
lsof -d 2-3
Shell
列出COMMAND列中包含字符串”sshd”,且⽂件描符的类型为txt的⽂件信息
命令:
lsof -c sshd -a -d txt
(12)杀死特定条件的进程
在某些情况我们可能希望结束占⽤特定⽬录的进程,可以结合kill命令使⽤,具体的命令如下
kill -9 `lsof -t -u zabbix`
kill -9 `lsof -t +D /home/mysql`
-t 选项之后表⽰结果只列出PID列,也就是进程ID列,其他列都忽略
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论