0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Linux lsof命令的基本用法

马哥Linux运维 来源:博客园sparkdev 2024-10-23 11:52 次阅读

lsof(list open files)是一个查看进程打开的文件的工具。

linux 系统中,一切皆文件。通过文件不仅仅可以访问常规数据,还可以访问网络连接和硬件。所以 lsof 命令不仅可以查看进程打开的文件、目录,还可以查看进程监听的端口等 socket 相关的信息。本文将介绍 lsof 命令的基本用法,本文中 demo 的演示环境为 ubuntu 18.04。

常用选项

-a指示其它选项之间为与的关系
-c<进程名> 输出指定进程所打开的文件
-d<文件描述符> 列出占用该文件号的进程
+d<目录> 输出目录及目录下被打开的文件和目录(不递归)
+D<目录> 递归输出及目录下被打开的文件和目录
-i<条件> 输出符合条件与网络相关的文件
-n不解析主机名
-p<进程号> 输出指定 PID 的进程所打开的文件
-P不解析端口号
-t只输出 PID
-u输出指定用户打开的文件
-U输出打开的 UNIX domain socket 文件
-h显示帮助信息
-v显示版本信息

基本输出

如果不带任何选项执行 lsof 命令,会输出系统中所有 active 进程打开的所有文件,结果就是我们被输出的信息所淹没,这没有任何的意义。我们先让 lsof 命令输出当前 Bash 进程打开的文件,并截取其中的一部分结果来介绍输出内容中都包含哪些信息:

991c1536-907d-11ef-a511-92fbcf53809c.png

COMMAND:程序的名称
PID:进程标识符
USER:进程所有者
FD:文件描述符,应用程序通过文件描述符识别该文件
TYPE:文件类型,如 DIR、REG 等
DEVICE:以逗号分隔设备编号
SIZE:文件的大小(bytes)
NODE索引节点(文件在磁盘上的标识)
NAME:打开文件的确切名称

下面简单介绍一下 FD 列和 TYPE 列中的常见内容。
FD 列中的常见内容有 cwd、rtd、txt、mem 和一些数字等等。其中 cwd 表示当前的工作目录;rtd 表示根目录;txt 表示程序的可执行文件;mem 表示内存映射文件:

994450dc-907d-11ef-a511-92fbcf53809c.png

还有一部分 FD 是以数字表示的,比如标准输入输出文件:

99589d1c-907d-11ef-a511-92fbcf53809c.png

数字后面的字母表示进程对该文件的读写模式,比如上图中的 u 表示该文件被打开并处于读取/写入模式。除了 u,还有 r 表示只读模式,w 表示只写模式,还可以同时应用 W 表示该进程拥有对文件写操作的锁。下图是截取的 docker daemon 进程打开的文件列表,其中显示了 FD 的不同模式:

996d6292-907d-11ef-a511-92fbcf53809c.png

TYPE 列中常见的 REG 和 DIR 分别表示普通文件和目录。而 CHR 和 BLK 则分别表示字符和块设备,unix、fifo 和 IPv4/IPv6 分别表示 UNIX domain 套接字、先进先出(FIFO)队列和 IPv4/IPv6 套接字。

下面我们来介绍一些 lsof 命令的常见用法。

查看哪些进程打开了某个文件

直接指定文件的名称作为 lsof 的参加就可以查看哪些进程打开了这个文件,下面的命令查询打开了 /bin/bash 文件的进程:

$ sudo lsof /bin/bash

9990458c-907d-11ef-a511-92fbcf53809c.png

除了普通文件,也可以是设备等文件(下面命令的输出很长,图示只是截取的一小部分):

$ sudo lsof /dev/sda1

99aa9b30-907d-11ef-a511-92fbcf53809c.png

查看哪些进程打开了某个目录及目录下的文件

这里分两种情况,+d 选项不执行递归查询,只查找那些打开了指定目录以及指定目录下文件和目录的进程,比如:

$ sudo lsof +d /var/log

99d26ffc-907d-11ef-a511-92fbcf53809c.png

+D 选项则会对指定的目录进行递归

$ sudo lsof +D /var/log

99ea48b6-907d-11ef-a511-92fbcf53809c.png

在卸载文件系统时,如果有进程打开了该文件系统中的文件或目录,卸载操作就会失败。因此最好在卸载文件系统前通过 lsof +D 检查文件系统的挂载点,杀掉相关的进程然后再执行卸载操作。

查看某个进程打开的所有文件

通过 -p 选项并指定进程的 PID 可以输出该进程打开的所有文件。比如我们想要查看 cron 程序打开的文件,可以先用 ps -C cron 命令查出进程的 PID:

9a0c5ce4-907d-11ef-a511-92fbcf53809c.png

然后把该 PID 传递给 lsof 命令的 -p 选项:

$ sudo lsof -p 1152

9a2c9b44-907d-11ef-a511-92fbcf53809c.png

组合多个选项

如果为 lsof 命令指定多个选项,这些选项间默认是或的关系。也就是说满足任何一个选项的结果都会被输出。可以添加额外的 -a 选项,它的作用就是让其它选项之间的关系变为与,比如下面的命令:

$ sudo lsof -a -p $$ -d0,1,2

9a6448fa-907d-11ef-a511-92fbcf53809c.png

其中的 -p 选项指定了当前进程的 PID,而 -d 选项则用来指定进程打开的文件描述符(可以通过逗号分隔多个文件描述符)。添加 -a 选项后,结果输出为当前进程打开的文件描述符为 0、1、2 的文件。
说明,-a 选项的使用有很多条件,具体请参考 lsof man page。

查看指定名称的程序打开的文件

通过 -c 选项可以匹配进程运行的程序(可执行文件)名称。比如我们要查找以字母 cr 开头的程序打开的文件列表:

$ sudo lsof -c cr

9a7ef934-907d-11ef-a511-92fbcf53809c.png

还可以同时指定多个 -c 选项,它们之间是或的关系。
如果想对 -c 选项的条件取反,只要在字符串前添加符号 ^ 就可以了,比如:

$ sudo lsof -c ^cr

-c 选项也支持正则表达式,比如下面的命令可以过滤出以 cra 和 cro 开头的程序打开的文件:

$ sudo lsof -c /cr[ao]/

查看被打开的与网络相关的文件

-i 选项用来查看被打开的和网络相关的文件,其参数的格式如下:
[46][protocol][@hostname|hostaddr][:service|port]
46表示 IP 协议的版本
protocol表示网络协议的名称,比如 TCP 或 UDP
hostname或 hostaddr 表示主机地址
service指 /etc/services 中的名称,比如 smtp 或多个服务的列表
port表示端口号,可以指定一个或多个

-i 选项默认会同时输出 IPv4 和 IPv6 打开的文件:

$ sudo lsof -i

9a97c892-907d-11ef-a511-92fbcf53809c.png

只列出 IPv4 或 IPv6 打开的文件

$ sudo lsof -i 4
$ sudo lsof -i 6

9aaee7d4-907d-11ef-a511-92fbcf53809c.png

列出与 22 号端口相关的文件

$ sudo lsof -i:22

9ac1e99c-907d-11ef-a511-92fbcf53809c.png

列出指定范围内被打开的 TCP 端口

$ sudo -i TCP:1-1024

9ad116e2-907d-11ef-a511-92fbcf53809c.png

查看被打开的 UNIX domain socket 文件

-U 选项输出打开的 UNIX domain socket 文件,这里我们结合 -c 选项来查看 ssh 服务打开的 UNIX domain socket 文件:

$ sudo lsof -a -c sshd -U

9af5085e-907d-11ef-a511-92fbcf53809c.png

查看某个用户打开的所有文件

-u 选项可以指定用户名或 user ID,并且和 -c 选项一样,可以通过逗号分隔多个用户名称或 user ID,也可以通过符号 ^ 对条件取反。
查看某个用户打开的所有文件

$ sudo lsof -u syslog

9b15baf4-907d-11ef-a511-92fbcf53809c.png

查看用户 nick 打开的网络相关的文件

$ sudo lsof -a -i -u nick

9b3565de-907d-11ef-a511-92fbcf53809c.png

排除某个用户

$ sudo lsof -i -u ^nick

9b54233e-907d-11ef-a511-92fbcf53809c.png

注意:在有排除条件时,不需要指定 -a 选项。

杀掉某个用户打开了文件的所有进程

$ kill -9 $(lsof -t -u nick)

该命令中的 -t 选项让 lsof 命令只输出进程的 PID:

9b693b02-907d-11ef-a511-92fbcf53809c.png

统计系统打开的文件总数

$ sudo lsof -P -n | wc -l

9b8b2384-907d-11ef-a511-92fbcf53809c.png

命令中的 -P 选项表示不解析端口号,-n 选项表示不解析主机名,这两个选项主要的目的是为了提升 lsof 命令的执行速度。wc -l 命令则用来统计 lsof 命令输出的行数。

恢复删除的文件

如果我们一不小心删除了文件,而又知道这个文本被某个进程打开着,就可以通过 lsof 命令来恢复该文件。具体的原理为:
当进程打开了某个文件时,只要该进程保持打开该文件,即使将文件删除,它依然存在于磁盘中。进程并不知道文件已经被删除,它仍然可以通过打开该文件时提供给它的文件描述符进行读取和写入。除了该进程之外,这个文件是不可见的,因为已经删除了其相应的目录索引节点。
进程打开的文件描述符就存放在 /proc/PID/fd 目录下。/proc 目录挂载的是在内存中所映射的一块区域,所以这些文件和目录并不存在于磁盘中,因此当我们对这些文件进行读取和写入时,实际上是在从内存中获取相关信息。lsof 程序就是使用这些信息和其他关于内核内部状态的信息来产生其输出。所以 lsof 可以显示进程的文件描述符和相关的文件名等信息。也就是说我们通过访问进程的文件描述符可以找到该文件的相关信息。
下面的 demo 演示如何通过 lsof 命令恢复被误删的 /var/log/syslog 文件。
先删除日志文件 /var/log/syslog,记着要提前备份一下这个文件,以防万一:

$ sudo rm /var/log/syslog

9b9cb932-907d-11ef-a511-92fbcf53809c.png

从上面的信息可以看到 PID 为 1141 的进程打开着该文件,文件描述符为 7,并且显示该文件已经被删除了。接下来我们通过 1141 号进程的文件文件描述符来查看该文件的内容:

$ sudo tail -n 5 /proc/1141/fd/7

9bb8c230-907d-11ef-a511-92fbcf53809c.png

上图说明文件 /var/log/syslog 文件的内容还在,并且可以通过文件描述符访问,接下来通过 IO 重定向的方式重新创建 /var/log/syslog 文件就可以了:

$ sudo sh -c 'cat /proc/1141/fd/7 > /var/log/syslog' 

然后修复文件的权限属性并重启 rsyslog 服务:

$ sudo chown syslog:adm /var/log/syslog
$ sudo systemctl restart rsyslog.service

这样就完成了 /var/log/syslog 文件的恢复工作。对于许多应用程序,尤其是日志文件和数据库文件,都可以通过这种方式来恢复。

帮助

-h 选项会输出 lsof 命令的帮助信息:

9be08cc0-907d-11ef-a511-92fbcf53809c.png

估计这样的帮助信息也只能逼着你去读 man page 了!

总结

lsof 并不是一个简单的命令,从其 man page 的长度就可以体会到这一点。从本文介绍的小 demo 入手或许可以让你忘记冗长的文档说明,一步步的开始使用并最终掌握这个命令。

链接:https://www.cnblogs.com/sparkdev/p/10271351.html

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Linux
    +关注

    关注

    87

    文章

    11170

    浏览量

    208469
  • 程序
    +关注

    关注

    115

    文章

    3747

    浏览量

    80663
  • 命令
    +关注

    关注

    5

    文章

    669

    浏览量

    21956
  • 进程
    +关注

    关注

    0

    文章

    200

    浏览量

    13933

原文标题:深入解析 Linux lsof 命令:网络排查利器与文件管理神器

文章出处:【微信号:magedu-Linux,微信公众号:马哥Linux运维】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    Linux find命令用法

    可以很肯定地说,find 命令Linux 后台开发人员必须熟知的操作之一,除非您使用的是 Windows Server。
    发表于 10-12 11:27 548次阅读

    linux运维命令大全

    仅是对Linux高端运维实用命令的简单汇总,不同的命令有相应用法和可实现的功能,具体使用方法,可自行查找!
    发表于 03-15 16:36

    linux中comm命令用法

    linux系统中comm命令用法详解 linux系统下的comm命令是一个非常实用的文件对比命令
    发表于 07-04 08:22

    Linux中的35个find命令用法

    Linux查找命令Linux系统中最重要和最常用的命令之一。查找用于根据与参数匹配的文件指定的条件来搜索和查找文件和目录列表的命令
    的头像 发表于 02-02 16:53 3602次阅读
    <b class='flag-5'>Linux</b>中的35个find<b class='flag-5'>命令</b><b class='flag-5'>用法</b>

    使用Linux命令lsof查看进程打开和查看文件的说明

    linux命令lsof 查看进程打开那些文件 或者 查看文件给那个进程使用对调试文件有很好的帮助和精准定位问题
    发表于 10-28 08:00 0次下载

    详谈Linux的find命令

    find 是 Linux 下最有用的命令之一,熟练的使用它对于提高工作效率很有帮助。下面介绍它的一些用法
    的头像 发表于 06-23 09:43 3036次阅读
    详谈<b class='flag-5'>Linux</b>的find<b class='flag-5'>命令</b>

    linux的scp命令怎么用_linux的grep命令用法

    linux中,scp命令用于Linux之间复制文件和目录,即在一台Linux服务器中将本地的文件上传到一台远端服务器,或将远端服务器的文件下载到本地。scp是
    发表于 09-04 15:36 4381次阅读
    <b class='flag-5'>linux</b>的scp<b class='flag-5'>命令</b>怎么用_<b class='flag-5'>linux</b>的grep<b class='flag-5'>命令</b><b class='flag-5'>用法</b>

    如何在Linux使用touch命令

    Linux touch命令用于更改文件时间戳。但touch命令的最常见用法是创建文件。
    的头像 发表于 12-05 17:21 1970次阅读

    Linux系统维护命令用法

    Linux有很多命令,每个命令基本可以用一篇文章介绍,本文仅简单总结一些常用系统维护命令用法
    的头像 发表于 04-17 14:57 960次阅读
    <b class='flag-5'>Linux</b>系统维护<b class='flag-5'>命令</b>的<b class='flag-5'>用法</b>

    Linux命令lsof应用

    linux环境下,任何事物都以文件的形式存在,通过文件不仅仅可以访问常规数据,还可以访问网络连接和硬件。
    发表于 08-31 10:20 315次阅读

    linux中source命令用法

    Linux中,source命令通常用于重新执行刚修改的初始化文件,使之立即生效,而不必注销并重新登录。source命令可以用于读取并执行脚本文件中的命令,通常用于在当前shell环境
    的头像 发表于 11-08 14:35 2049次阅读

    linux查看物理接口的命令

    Linux操作系统提供了多种命令和工具来查看物理接口。在这篇文章中,我们将详细介绍一些最常用和常见的命令,以及它们的用法和输出。 ifconfig
    的头像 发表于 11-16 16:48 1042次阅读

    linux常用命令用法

    Linux是一种开源的操作系统,它以稳定、高效和安全的特点受到广大用户的喜爱。掌握Linux的常用命令及其用法对于操作系统的管理和开发都至关重要。本文将详尽、详实、细致地介绍
    的头像 发表于 11-17 09:47 589次阅读

    总结linux命令行的主要用法

    Linux命令行是一种在Linux操作系统中通过文本界面来执行指令和管理系统的方式。它提供了丰富的功能和灵活性,帮助用户完成各种任务。本文将详细介绍Linux
    的头像 发表于 11-17 10:19 579次阅读

    Linux查看IO状态的常用命令都有哪些呢?

    介绍下Linux的3个常用I/O相关命令,解决I/O压力过大问题时用iostat,查看磁盘的I/O状态用iotop,查看I/O进程排名用lsof
    的头像 发表于 01-16 09:28 4769次阅读