Linux下 lsof 命令详解

Linux下 lsof 命令详解
lsof 是 List Open File 的缩写, 它主要用来获取被进程打开文件的信息,我们都知道,在Linux中,一切皆文件,lsof命令可以查看所有已经打开了的文件,比如: 普通文件,目录,特殊的块文件,管道,socket套接字,设备,Unix域套接字等等,同时,它还可以结合 grep 以及 ps 命令进行更多的高级搜索

安装

lsof 命令默认是没有安装的,而且它的使用需要有root权限或者赋予普通用于sudo权限, 使用以下命令安装

yum install -y lsof

lsof 命令有很多可选参数,本文根据我自己的使用经验整理了一些比较常用且重要的用法

列出所有打开的文件

不带任何参数执行 lsof 命令会输出当前所有活跃进程打开的所有文件

[root@ecs-centos-7 ~]# lsof | more
COMMAND     PID   TID    USER   FD      TYPE             DEVICE  SIZE/OFF       NODE NAME
systemd       1          root  cwd       DIR              253,1      4096          2 /
systemd       1          root  rtd       DIR              253,1      4096          2 /
systemd       1          root  txt       REG              253,1   1624520     530313 /usr/lib/systemd/systemd
systemd       1          root  mem       REG              253,1     20064     528340 /usr/lib64/libuuid.so.1.3.0
systemd       1          root  mem       REG              253,1    265600     532853 /usr/lib64/libblkid.so.1.1.0
systemd       1          root  mem       REG              253,1     90248     525942 /usr/lib64/libz.so.1.2.7
systemd       1          root  mem       REG              253,1    157424     525955 /usr/lib64/liblzma.so.5.2.2
systemd       1          root  mem       REG              253,1     23968     526159 /usr/lib64/libcap-ng.so.0.0.0
systemd       1          root  mem       REG              253,1     19896     526135 /usr/lib64/libattr.so.1.1.0
systemd       1          root  mem       REG              253,1     19288     525996 /usr/lib64/libdl-2.17.so
systemd       1          root  mem       REG              253,1    402384     525931 /usr/lib64/libpcre.so.1.2.0
systemd       1          root  mem       REG              253,1   2156160

由于 lsof命令会输出很多信息,所以上面例子中使用了 lsof | more 来分页显示命令输出结果

输出结果中,第一列中 systemd 的进程ID是 1,它是一个守护进程

其中列 COMMANDPIDUSER 分别表示进程名、进程ID、所属用户

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 表示路径或者链接

列出指定用户已打开的文件

使用 -u 选项可以列出指定用户已经打开的文件,该选项后面可以接多个用户名,每个用户名之间用空格隔开,表示列出所有指定用户已打开的所有文件

[root@ecs-centos-7 ~]# lsof -u tt | more
COMMAND   PID USER   FD   TYPE DEVICE  SIZE/OFF   NODE NAME
bash    27789   tt  cwd    DIR  253,1      4096 131090 /home/tt
bash    27789   tt  rtd    DIR  253,1      4096      2 /
bash    27789   tt  txt    REG  253,1    964600 525779 /usr/bin/bash
vim     27813   tt  txt    REG  253,1   2337192 531847 /usr/bin/vim
vim     27813   tt    4u   REG  253,1     12288 131167 /home/tt/.p.txt.swp

上面的例子中, lsof -u tt 命令表示列出 tt 用户已经打开了的文件,从结果可以看出,用户打开了 /home/tt//usr/bin/bash/usr/bin/vim/home/tt/.p.txt.swp 这几个文件

如果要排除指定用户已经打开的文件,可以在用户名前加 ^ 符号,下面的命令会列出除 tt用户外其他所有用户已打开了的文件

lsof -u ^tt | more

找出打开着但已被删除了的文件

有这样一种场景,有一个服务正在往日志文件中写日志,这个时候,不小心把正在写入的日志文件删除了

上面的场景中,日志文件虽然被删除了,但是文件仍然是打开着的,它仍然占用文件系统的空间,我们可以结合 grep 命令找出这种打开着,但是已经被删除的文件

[root@ecs-centos-7 ~]# lsof -u tt | grep deleted
vim     27813   tt    4u   REG  253,1    12288 131167 /home/tt/.p.txt.swp(deleted)

上面例子中使用 lsof -u tt | grep deleted 命令查看用户 tt打开着的确被删除的文件

从结果可以看出,在往 p.txt写入内容的时候,文件被删除了

列出所有打开了的网络文件

[root@ecs-centos-7 ~]# lsof -i
COMMAND    PID  USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
ntpd       567   ntp   18u  IPv4  12657      0t0  UDP localhost:ntp
ntpd       567   ntp   22u  IPv6  16095      0t0  UDP ecs-centos-7.4-64bit-20200212:ntp
dhclient   651  root    6u  IPv4  14594      0t0  UDP *:bootpc
master     960  root   13u  IPv4  15791      0t0  TCP localhost:smtp (LISTEN)
master     960  root   14u  IPv6  15792      0t0  TCP localhost:smtp (LISTEN)
mysqld    1053 mysql   13u  IPv6  15147      0t0  TCP *:mysql (LISTEN)
sshd      1348  root    3u  IPv4  16698      0t0  TCP *:ssh (LISTEN)
  • 列出所有 IPV4/6 网络文件

列出所有已经打开了的 ipv4 网络文件

[root@ecs-centos-7 ~]# lsof -i 4
COMMAND    PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
ntpd       567  ntp   16u  IPv4  12651      0t0  UDP *:ntp
ntpd       567  ntp   18u  IPv4  12657      0t0  UDP localhost:ntp
ntpd       567  ntp   21u  IPv4  16094      0t0  UDP ecs-centos-7.4-64bit-20200212:ntp
dhclient   651 root    6u  IPv4  14594      0t0  UDP *:bootpc
master     960 root   13u  IPv4  15791      0t0  TCP localhost:smtp (LISTEN)
sshd      1348 root    3u  IPv4  16698      0t0  TCP *:ssh (LISTEN)

所有已经打开了的 ipv6 网络文件

[root@ecs-centos-7 ~]# lsof -i 6
COMMAND  PID  USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
ntpd     567   ntp   17u  IPv6  12652      0t0  UDP *:ntp
ntpd     567   ntp   19u  IPv6  12658      0t0  UDP localhost:ntp
ntpd     567   ntp   22u  IPv6  16095      0t0  UDP ecs-centos-7.4-64bit-20200212:ntp
master   960  root   14u  IPv6  15792      0t0  TCP localhost:smtp (LISTEN)
mysqld  1053 mysql   13u  IPv6  15147      0t0  TCP *:mysql (LISTEN)
sshd    1348  root    4u  IPv6  16700      0t0  TCP *:ssh (LISTEN)
  • 列出在指定端口上打开的文件

使用 lsof -i:端口号 可以获得所有在指定端口号上打开的文件

[root@ecs-centos-7 ~]# lsof -i:22
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
sshd     1348 root    3u  IPv4  16698      0t0  TCP *:ssh (LISTEN)
sshd     1348 root    4u  IPv6  16700      0t0  TCP *:ssh (LISTEN)
sshd    27741 root    3u  IPv4 458958      0t0  TCP ecs-centos-7.4-64bit-20200212:ssh->113.118.121.220:42395 (ESTABLISHED)
sshd    27819 root    3u  IPv4 459250      0t0  TCP ecs-centos-7.4-64bit-20200212:ssh->113.118.121.220:19807 (ESTABLISHED)
sshd    27895 root    3u  IPv4 459828      0t0  TCP

上面例子列出了所有在22号端口上打开的文件

在服务器开发中,经常会部署一个网关或者代理程序,用来和客户端通讯,网关或者代理程序需要开放一个固定的端口供客户端连接用

如果客户端连接不上网关或者代理程序,我们可以用上述命令检查网关或代理程序的端口是否开启,来排除因为端口关闭了导致连接不上网关的情况

  • 列出使用了指定协议(TCP/UDP) 的文件

使用 lsof -i TCP/UDP 列出使用了TCP 或 UDP 协议的文件

[root@cghost8 /home/cgyx]# lsof -i TCP | more
COMMAND      PID   USER   FD   TYPE  DEVICE SIZE/OFF NODE NAME
sshd        1704   root    3u  IPv4   13593      0t0  TCP *:ssh (LISTEN)
sshd        1704   root    4u  IPv6   13595      0t0  TCP *:ssh (LISTEN)
redis-serer   1725   root    4u  IPv4   19773      0t0  TCP localhost:6380 (LISTEN)
nc          2067   cgyx    4u  IPv4   39167      0t0  TCP *:60600 (LISTEN)
mysqld      3020  mysql    4u  IPv6 5514608      0t0  TCP 192.168.70.10:mysql->192.168.70.10:37084 (ESTABLISHED)

使用 lsof -i TCP:3306 列出使用了TCP 协议并且端口为3306的文件

[root@cghost8 /home/cgyx]# lsof -i TCP:3306
COMMAND      PID  USER   FD   TYPE  DEVICE SIZE/OFF NODE NAME
mysqld      3020 mysql    4u  IPv6 5514608      0t0  TCP 192.168.70.10:mysql->192.168.70.10:37084 (ESTABLISHED)

使用 lsof -i TCP:1-1024 列出使用了TCP协议并且端口范围为 1 到 1024 的文件

[root@cghost8 /home/cgyx]# lsof -i TCP:1-1024
COMMAND   PID   USER   FD   TYPE  DEVICE SIZE/OFF NODE NAME
sshd     1704   root    3u  IPv4   13593      0t0  TCP *:ssh (LISTEN)
sshd     1704   root    4u  IPv6   13595      0t0  TCP *:ssh (LISTEN)
cupsd    1709   root   12u  IPv6   39148      0t0  TCP localhost:ipp (LISTEN)
cupsd    1709   root   13u  IPv4   39149      0t0  TCP localhost:ipp (LISTEN)
smbd     1824   root   35u  IPv6   17658      0t0  TCP *:microsoft-ds (LISTEN)
smbd     1824   root   36u  IPv6   17659      0t0  TCP *:netbios-ssn (LISTEN)
smbd     1824   root   37u  IPv4   17660      0t0  TCP *:microsoft-ds (LISTEN)
smbd     1824   root   38u  IPv4   17661      0t0  TCP *:netbios-ssn (LISTEN)

列出目录中所有打开的文件

可以使用 lsof命令列出指定目录中的所有打开文件

现有一个 data目录 ,结构如下:

[root@ecs-centos-7 tt]# tree data/
data/
├── dira
│   └── a.txt
└── d.s

1 directory, 2 files

列出 data 目录中打开的文件

[root@ecs-centos-7 tt]# lsof +D ./data/
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF   NODE NAME
bash    28473 root  cwd    DIR  253,1     4096 131146 ./data
bash    28502 root  cwd    DIR  253,1     4096 131172 ./data/dira
vim     28530 root  cwd    DIR  253,1     4096 131172 ./data/dira
vim     28530 root    4u   REG  253,1    12288 131174 ./data/dira/.a.txt.swp

[root@ecs-centos-7 tt]# lsof +d ./data/
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF   NODE NAME
bash    28473 root  cwd    DIR  253,1     4096 131146 ./data
bash    28502 root  cwd    DIR  253,1     4096 131172 ./data/dira
vim     28530 root  cwd    DIR  253,1     4096 131172 ./data/dira

上面例子中, +D+d 选项都是列出目录中打开的文件

+D 选项会列出一个目录和其子目录中打开的文件,而 +d 选项只会列出当前目录下已打开的文件

列出指定进程ID打开的文件

进程ID是操作系统进程的唯一标识,以下命令列出了进程ID为 1053 相关的文件, 从结果中可以知道这个进程ID对应的进程是MySQL

[root@ecs-centos-7 ~]# lsof -p 1053
COMMAND  PID  USER   FD   TYPE             DEVICE  SIZE/OFF    NODE NAME
mysqld  1053 mysql  cwd    DIR              253,1      4096 1055765 /var/lib/mysql
mysqld  1053 mysql  rtd    DIR              253,1      4096       2 /
mysqld  1053 mysql  txt    REG              253,1 251841448  534935 /usr/sbin/mysqld
mysqld  1053 mysql  mem    REG              253,1    209512  659436 /usr/lib64/mysql/plugin/validate_password.so
mysqld  1053 mysql    1w   REG              253,1    206658  924771 /var/log/mysqld.log
mysqld  1053 mysql    2w   REG              253,1    206658  924771 /var/log/mysqld.log

上述命令中, -p 选项后面可以指定多个进程ID,每个进程ID之间用逗号分隔,如果想排除掉某个进程打开的文件,可以在该进程ID前面加上 ^符号

lsof -p 1,2,3,^4

上述命令会列出进程1,进程2,进程3打开的所有文件,同时忽略进程4打开的文件

杀死指定用户的所有进程

前面介绍了列出指定用户所有打开的文件,我们可以组合 kill 命令一起使用,实现杀死指定用户的所有进程的功能,具体的命令如下

kill -9 lsof -t -u tt

上述命令中, lsof -u tt 是列出 tt用户所有打开的文件,加上 -t 选项之后表示结果只列出PID列,也就是进程ID列,其他列都忽略,前面的 kill -9 表示强制结束指定的进程ID

小结

本文介绍了 lsof 命令的一些常见用法,它还有很多其他的用法,请自行查看man文档

Original: https://www.cnblogs.com/wanng/p/lsof-cmd.html
Author: Linux开发那些事儿
Title: Linux下 lsof 命令详解

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/606806/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 27. rz与sz上传下载文件

    工作中需要在 Linux 和 Windows 之间传输文件,一般使用xftp等gui工具完成。但是有些第三方linux命令也可以完成上传下载操作 从Linux下载文件到本机 , 在…

    Linux 2023年5月27日
    071
  • 《卡死你3000》批量修改被控机密码,秘钥

    批量生成密码之产生随机数: 默认产生16位大小写加数字密码 批量生成密码,并写入nodelist.csv: cs产生所有被控机旧密码并写入nodelist.ps1 运行这个脚本后,…

    Linux 2023年6月13日
    065
  • phpcms如何在前台文章列表前显示所属类别名称

    最近做单位网站模版遇到的问题,欲实现的效果: 但是phpcms中自带的文章列表标签没有这个功能,数据库中文章表中也只有类别id的字段,因此不能通过简单的{$r[catname]}读…

    Linux 2023年6月13日
    087
  • 全新UI西游H5决战天宫游戏详细图文架设教程

    前言 想体验经典Q版西游霸服快乐吗?想体验满级VIP的尊贵吗?想体验一招秒杀的爽快吗?各种极品炫酷时装、坐骑、翅膀、宠物通通给你,就在全新UI西游H5决战天宫! 本文讲解决战天宫架…

    Linux 2023年6月7日
    089
  • 对比nushell和powershell

    2021-07-17 第一版 有些对比领域缺失,这篇文章会持续更新。 这是一篇对比powershell和nushell的文章。我是powerhsell专家,又是nushell新手,…

    Linux 2023年6月14日
    096
  • 五、用户管理

    id root查看用户uiduid 0管理员uid 1-999系统账号uid 1000-60000普通账号gid 0 管理组gid 1-999 系统组gid 1000-60000 …

    Linux 2023年6月7日
    066
  • Linux 时间操作及其同步

    本文将以 Arch Linux 为例,讨论 Linux 的时间操作和同步方法。 操作系统的时间 (clock) 由三或四部分决定: 时间值; 是否为 UTC 时间; 时区; (如果…

    Linux 2023年5月27日
    088
  • 分布式计算的本质、特点和未来

    在计算机早期,都是由一台主机承担全部存储和计算工作,这种方式被称为集中处理。后来随着处理器发展和网络出现,衍生出客户机/服务器架构,即由服务器完成主要的存储计算工作,客户机则负责较…

    Linux 2023年6月6日
    0107
  • Linux内核软中断

    1 软中断概述 软中断是实现中断下半部的一种手段,与2.5以前版本的下半段机制不同。软中断可以同时运行在不同的CPU上。 1.1 软中断的表示 内核中用结构体softirq_act…

    Linux 2023年6月7日
    077
  • go-切片的追加

    // The append built-in function appends elements to the end of a slice. If // it has suffi…

    Linux 2023年6月13日
    068
  • Redis 为什么使用单进程单线程方式也这么快(转载)

    Redis 采用的是基于内存的采用的是单进程单线程模型的 KV 数据库,由 C 语言编写。官方提供的数据是可以达到100000+的 qps。这个数据不比采用单进程多线程的同样基于内…

    Linux 2023年5月28日
    072
  • JAVA中如何将以Date型的数据保存到数据库以Datetime型的字段中

    用Timestamp就行了 recordOuttime是Date类型 import java.sql.Timestamp; Record record = recordMapper…

    Linux 2023年6月8日
    068
  • Ubuntu报Command ‘firewall-cmd’ not found, but can be installed with: apt install firewalld错误解决方案

    当输入 firewall-cmd –list-ports 查看端口信息时报错 报错的原因可能是没有安装firewall,安装命令为: yum install firewalld …

    Linux 2023年6月7日
    085
  • Linux常用命令

    基本操作 创建目录: mkdir xxx 删除目录: rm -rf xxx 切换目录: cd xxx,返回: cd – 创建文件: touch xxx.txt 复制文件: cp x…

    Linux 2023年6月8日
    0108
  • 如何获取 Docker 容器的 IP 地址

    查询单个容器 IP 地址: 使用下面命令可以查看容器详细信息,里面包含 IP 地址信息: docker inspect <container id> </cont…

    Linux 2023年6月7日
    084
  • WEB自动化-06-命令行运行Cypress

    6 命令行运行Cypress Cypress命令行的运行基本语法格式如下所示: cypress <command> [options] command代表运行的命令,是…

    Linux 2023年6月7日
    0109
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球