linux分析工具之lsof详解 linux&shell学习系列

一、概述

      在linux中,所有东西都是以文件的形式存在的,所以我们在linux上的操作都是通过对文件的操作来执行我们所需要的逻辑,比如我们对文件数据的访问,修改,访问网络的连接等,刚好lsof(list open file)命令用于查看进程打开的文件,打开文件的进程,进程打开的端口(TCP、UDP)。找回/恢复删除的文件。是十分方便的系统监视工具,因为lsof命令需要访问核心内存和各种文件,所以需要root用户执行

安装命令:yum install lsof  #centos系统

二、语法和内容含义

2.1、使用语法

语法:lsof [options] filename

常用选项:

无选项       #默认列出所有打开的文件相关信息
file        #列出打开文件存在的进程
-a          #使用AND逻辑,合并选项输出内容
-c<进程名>   #列出指定进程所打开的文件
-g          #列出GID号进程详情
-d<文件号>   #列出占用该文件描述符的进程
+d<目录>     #列出目录下被打开的文件
+D<目录>     #递归列出目录下被打开的文件
-n<目录>     #列出使用NFS的文件
-i<条件>     #列出符合条件的进程。(4、6、协议、:端口、 @ip )
-p<进程号>   #列出指定进程号所打开的文件
-u          #列出UID号进程详情
-U          #获取 UNIX 套接口地址
-t          #列出进程
-h          #显示帮助信息
-v          #显示版本信息

2.2、内容含义

首先我们使用lsof | head 命令查看一下

[root@lgh ~]# lsof | head
COMMAND     PID           USER   FD      TYPE             DEVICE  SIZE/OFF       NODE NAME
init          1           root  cwd       DIR              253,0      4096          2 /
init          1           root  rtd       DIR              1           root  txt       REG              0    150352    8519721 /sbin/init
init          1           root  mem       REG              0     66432    1310749 /lib64/libnss_files-2.12.so
init          1           root  DEL       REG              0              1310733 /lib64/libc-1310744 /lib64/libgcc_s-4.4.7-20120601.so.1.#prelink#.AXbpAw
init          1310761 /lib64/librt-1310757 /lib64/libpthread-.so.#prelink#.6p24pv
init          1310783 /lib64/libdbus-1.so.3.4.0.#prelink#.M6wKKU
lsof -R +d /dev | head 命令查看一波(主要看FD这列),并且相比上面增加了PPID列
[root@mwpl003 ~]# lsof -R +d /dev | head
COMMAND     PID  PPID           USER   FD   TYPE             DEVICE SIZE/OFF  NODE NAME
init          1     0           root    0u   CHR                1,1)">3      0t0  4025 /dev/null1u   CHR                2u   CHR                
udevd      1872     1           root    
rserver    3375     1 rstudio-server    null

每列的基本含义如下:

COMMAND:进程的名称
PID:进程标识符
PPID:父进程标识符(需要指定-R参数)
USER:进程所有者
FD:文件描述符,应用程序通过文件描述符识别该文件。
TYPE:文件类型
DEVICE:指定磁盘的名称
SIZE/OFF:文件的大小
NODE:索引节点(文件在磁盘上的标识)
NAME:打开文件的确切名称

其中FD文件描述符列表如下:

cwd:表示current work dirctory,即:应用程序的当前工作目录,这是该应用程序启动的目录,除非它本身对这个目录进行更改
txt:该类型的文件是程序代码,如应用程序二进制文件本身或共享库,如上列表中显示的 /sbin/init 程序
lnn:library references (AIX);
er:FD information error (see NAME column);
jld:jail directory (FreeBSD);
ltx:shared library text (code and data);
mxx :hex memory-mapped type number xx.
m86:DOS Merge mapped file;
mem:memory-mapped file;
mmap:memory-mapped device;
pd:parent directory;
rtd:root directory;
tr:kernel trace file (OpenBSD);
v86 VP/ix mapped file;
0:表示标准输出
:表示标准输入
2:表示标准错误

一般在标准输出、标准错误、标准输入后还跟着文件状态模式:
u:表示该文件被打开并处于读取/写入模式。
r:表示该文件被打开并处于只读模式。
w:表示该文件被打开并处于。
空格:表示该文件的状态模式为unknow,且没有锁定。
-:表示该文件的状态模式为unknow,且被锁定。

其中TYPE文件类型列表如下:

DIR:表示目录
CHR:表示字符类型
BLK:块设备类型
UNIX:UNIX域套接字
FIFO:先进先出(FIFO)队列
IPv4:网际协议(IP)套接字

三、实践

1、lsof -a -u root -d 2 | head   #列出是root用户,并且DF为2的文件,-a只有两者满足都满足要求才列出

[root@lgh ~]# lsof -a -u root -d 2 | head 
COMMAND     PID USER   FD   TYPE DEVICE SIZE/OFF    NODE NAME
init          1 root    2u   CHR    3      0t0    1872 root    
auditd     3525 root    
rsyslogd   3559 root    2w   REG  2092 4457009 /var/log/messages
irqbalanc  3594 root    
cupsd      3689 root    2w   CHR    
acpid      3721 root    
hald-runn  3734 root    
hald-addo  3774 root    null

2、lsof +d /bin/  #显示/bin当前目录下所有打开的文件,如果是想递归的打开则使用选项 +D即可

[root@lgh ~]# lsof +d /bin/
COMMAND     PID USER  FD   TYPE DEVICE SIZE/OFF     NODE NAME
dbus-daem  3668 dbus txt    REG  0   339080 12582956 /bin/dbus-daemon
bash       6012 root txt    REG  942200 12582957 /bin/bash
dbus-daem  9311  gdm txt    REG  daemon
bash      11017 root txt    REG  12582957 /bin/bash

3、lsof -i | head -20 | tail  #使用 -i 选项显示网络连接

[root@lgh ~]# lsof -i | head -20 | tail
rpcbind    3612            rpc    8u  IPv4     16143      0t0  TCP *:sunrpc (LISTEN)
rpcbind    9u  IPv6     16144      0t0  UDP *:sunrpc 
rpcbind    3612            rpc   10u  IPv6     16145      0t0  UDP *:819 
rpcbind    11u  IPv6     16146      0t0  TCP *:sunrpc (LISTEN)
rpc.statd  3634        rpcuser    5r  IPv4     16223      0t0  UDP localhost.localdomain:842 
rpc.statd  3634        rpcuser    16228      0t0  UDP *:536369u  IPv4     16231      0t0  TCP *:36415 (LISTEN)
rpc.statd  3634        rpcuser   16234      0t0  UDP *:5210816237      0t0  TCP *:38611 (LISTEN)
cupsd      3689           root    6u  IPv6     16394      0t0  TCP localhost.localdomain:ipp (LISTEN)

4、lsof -i 4 | head  #仅获取IPV4的流量 ,如果想获取IPV6的流量的话,把4改成6即可

[root@lgh ~]# lsof -i 4 | head
COMMAND     PID           USER   FD   TYPE    DEVICE SIZE/OFF NODE NAME
haproxy    1523           root    0u  IPv4    871803      0t0  UDP *:50203 
haproxy    4u  IPv4    871797      0t0  TCP *:ff-fms (LISTEN)
haproxy    5u  IPv4    871798      0t0  TCP *:panagolin-ident (LISTEN)
haproxy    6u  IPv4    871799      0t0  TCP *:scp-config (LISTEN)
rserver    3375 rstudio-server    6u  IPv4     15668      0t0  TCP *:msgsrvr (LISTEN)
rsyslogd   3559           root    4u  IPv4     15950      0t0  UDP *:syslog 
rpcbind    16141      0t0  UDP *7u  IPv4     16142      0t0  UDP *:16143      0t0  TCP *:sunrpc (LISTEN)

5、lsof -itcp |head #显示所有tcp连接,如果想显示udp连接就把tcp改成udp即可

[root@lgh~]# lsof -itcp |head
COMMAND     PID           USER   FD   TYPE    DEVICE SIZE/:msgsrvr (LISTEN)
rpcbind    16394      0t0  TCP localhost.localdomain:ipp (LISTEN)

6、lsof -i@192.168.88.133  #使用-i@host显示该主机是否连接了指定主机,使用-i@host:port显示该主机是否通过某个指定端口连接指定主机

[root@lgh ~]# lsof -i@192.168.88.133
COMMAND    PID      USER   FD   TYPE    DEVICE SIZE/OFF NODE NAME
java     20380 zookeeper   31u  IPv4 207875803      0t0  TCP lgh:macbak->lgh1:60670 (ESTABLISHED)
java     33u  IPv4 207875808      0t0  TCP lgh:40232->lgh1:bmcpatrolagent (ESTABLISHED)
java     46u  IPv4 207879310      0t0  TCP lgh:eforward->lgh1:40134 (ESTABLISHED)
catalogd 21822    impala  277u  IPv4 207882990      0t0  TCP lgh:40964->lgh1:med-ltp (ESTABLISHED)
catalogd 278u  IPv6 207882991      0t0  TCP lgh:23020->lgh1:40058279u  IPv6 207882992      0t0  TCP lgh:40060 (ESTABLISHED)
You have mail in /var/spool/mail/root
[root@lgh ~]# lsof -i@192.168.88.133:60670
COMMAND   PID      USER   FD   TYPE    DEVICE SIZE/OFF NODE NAME
java    60670 (ESTABLISHED)

7、lsof -i -stcp:LISTEN |head #找出所有监听的文件,把LISTEN换成ESTABLISHED表示显示所有建立连接的文件

[root@lgh ~]# lsof -i -stcp:LISTEN |head    
COMMAND     PID           USER   FD   TYPE    DEVICE SIZE/16394      0t0  TCP localhost.localdomain:ipp (LISTEN)

8、lsof -u root | head #指定root用户打开的所有文件,可以通过 -u ^root取反,表示非root用户打开的文件,kill -9 `lsof -u hive -t` 表示杀掉hive所有的进程

[root@lgh ~]# lsof -u root | head
COMMAND     PID USER   FD      TYPE             DEVICE SIZE/1 root  cwd       DIR              1 root  rtd       DIR              1 root  txt       REG              1 root  mem       REG              1 root  DEL       REG              0             1.#prelink#.AXbpAw

9、 lsof -c haproxy  #显示指定haproxy命令的连接文件,使用-p参数则是指定端口

[root@lgh ~]# lsof -c haproxy
COMMAND  PID USER   FD   TYPE             DEVICE SIZE/OFF     NODE NAME
haproxy 1523 root  cwd    DIR              4096 57939112 /data/hive/transfer_baseinfo
haproxy 1523 root  rtd    DIR              4096        
haproxy 1523 root  txt    REG              0  3769897  2376812 /usr/local/sbin/haproxy
haproxy 1523 root  DEL    REG              0           .so
haproxy 1310836 /lib64/ld-1523 root    0u  IPv4             871803      0t0      UDP *: 
haproxy 3u  unix 0xffff88204e2343c0      0t0   871795 /var/run/haproxy/info.sock.1522.tmp
haproxy 4u  IPv4             871797      0t0      TCP *:ff-fms (LISTEN)

 

四、数据恢复

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

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

    lsof 程序使用该信息和其他关于内核内部状态的信息来产生其输出。所以lsof 可以显示进程的文件描述符和相关的文件名等信息。也就是我们通过访问进程的文件描述符可以找到该文件的相关信息。当系统中的某个文件被意外地删除了,只要这个时候系统中还有进程正在访问该文件,那么我们就可以通过lsof从/proc目录下恢复该文件的内容

我们使用 /var/log/messages做测试:

首先我们用lsof查看下/var/log/messages这个文件的连接

[root@lgh2 fd]# lsof | grep messages
rsyslogd  6511         root    6w      REG              647273   34816846 /messages
in:imjour 6511 6543    root    6w      REG              messages
rs:main   6553    root    6w      REG              var/log/messages

然后我们使用命令rm  -f  /var/log/messages删除文件,继续使用lsof命令查看,已经显示删除

[root@lgh2 fd]# lsof | grep messages   
rsyslogd  messages (deleted)
messages (deleted)
rs:main   var/log/messages (deleted)

然后我们cd /proc/6511/fd   #6511表示进程号,然后我们ll查看一下目录

[root@lgh2 fd]# ll
total 
lr-x------ 1 root root 64 Oct 12 04:22 0 -> /dev/
l-wx------ 1 -> /dev/2 -> /dev/3 -> anon_inode:inotify
lrwx------ 4 -> socket:[36279]
lr-x------ 5 -> /run/log/journal/0b933fe64005419d8f16599287df47be/system.journal
l-wx------ 1 root root 64 Oct 12 04:22 6 -> /var/log/messages (deleted) #这里发现6这个文件描述符指向这个文件/var/log/messages

我们cat查看一下6这个文件

[root@lgh2 fd]# cat 6 | head -20  #这个文件就是我们对应的/var/log/messages文件
Sep 03:12:45 lgh2 chronyd[6237]: Selected source 120.25.115.206237]: System clock wrong by -43210.956291 seconds,adjustment started
Sep 15:01 lgh2 systemd: Started Session 881 of user root.
Sep 21 lgh2 systemd: Time has been changed
Sep 27 lgh2 chronyd[6237]: Forward time jump detected!6237]: Can't synchronise: no selectable sources
Sep 17:36 lgh2 chronyd[119.28.183.18443211.80700618:23 lgh2 chronyd[41 lgh2 chronyd[20:88288326 lgh2 chronyd[22:5.79.108.3443211.56270055 lgh2 chronyd[25:88422 lgh2 systemd: Time has been changed

然后我们使用命令 cat /proc/6511/fd/6 > /var/log/messages 还原数据,然后我们继续使用lsof命令查看

[root@lgh2 fd]# lsof |0       213   34816872 /var/log/messages

还原成功了

 

更多linux文章请见:linux&shell学习系列

 

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


linux常用进程通信方式包括管道(pipe)、有名管道(FIFO)、信号(signal)、消息队列、共享内存、信号量、套接字(socket)。管道用于具有亲缘关系的进程间通信,有名管道的每个管道具有名字,使没有亲缘关系的进程间也可以通信。信号是比较复杂的通信方式,用于通知接受进程有某种事件发生,除
Linux性能观测工具按类别可分为系统级别和进程级别,系统级别对整个系统的性能做统计,而进程级别则具体到进程,为每个进程维护统计信息。&#xD;&#xA;&#xD;&#xA;按实现原理分,可分为基于计数器和跟踪以及剖析。含义如下:&#xD;&#xA;&#xD;&#xA;计数器:内核维护的统计数据,通常为无符号整型,用于对发生的事件计数,比如,网络包接收计数器,磁
本文详细介绍了curl命令基础和高级用法,包括跳过https的证书验证,详细追踪整个交互过程,可用于调用网络后端接口,诊断http和https网络服务故障。
本文包含作者工作中常用到的一些命令,用于诊断网络、磁盘占满、fd泄漏等问题。命令包括ping、fping、tcpdump、lsof、netstat、/proc/$pid/fd、du、grep、traceroute、dig。
linux的平均负载表示运行态和就绪态及不可中断状态(正在io)的进程数目,用uptime查看到负载很高,既有可能是CPU利用率高,也可能是大量在等待io的进程导致,用mpstat查看每个CPU的使用情况,查看CPU的使用率或者CPU花在等待io的时间,接着用pidstat定位具体的进程
CPU上下文频繁切换会导致系统性能下降,切换分为进程切换、线程切换及中断切换,进程切换的开销较大,除了需要保存寄存器和程序计数器中的值还需保存全局变量、栈等到内存中,以便下次运行恢复,而同一进程中的线程切换开销会小很多,只需更新寄存器和线程独有的栈,共享资源如打开的文件、全局变量等无需切换,当硬件中
1.top命令 作用:该命令可以按CPU使用.内存使用和执行时间对任务进行排序,常用来监控系统中占用CPU或内存较高的程序及CPU和内存的负载。 默认视图: 当想看系统负载时,可观察汇总的%CPU中的us用户进程和sy系统进程是否占用CPU很高,相加接近100%就说明占用很高了,有些程序可能得不到及
文章浏览阅读1.8k次,点赞63次,收藏54次。Linux下的目录权限!!!粘滞位!!!超详解!!!
文章浏览阅读1.6k次,点赞44次,收藏38次。关于Qt的安装、Windows、Linux、MacBook_mack book 安装qt
本文介绍了使用shell脚本编写一个 Hello
文章浏览阅读1.5k次,点赞37次,收藏43次。【Linux】初识Linux——了解操作系统的发展历史以及初次体验Linux编程环境
文章浏览阅读3k次,点赞34次,收藏156次。Linux超详细笔记,个人学习时很认真的记录的,觉得好的麻烦点个赞。
文章浏览阅读6.8k次,点赞109次,收藏114次。【Linux】 OpenSSH_9.3p1 升级到 OpenSSH_9.5p1(亲测无问题,建议收藏)_openssh_9.5p1
文章浏览阅读3.5k次,点赞93次,收藏78次。初识Linux中的线程,理解线程的各种概念,理解进程地址空间中的页表转换,介绍pthread线程库并理解线程库!
文章浏览阅读863次。出现此问题为Linux文件权限问题,解决方案为回到引擎目录执行命令。输入用户密码后运行./UnrealEditor。_increasing per-process limit of core file size to infinity.
文章浏览阅读2.9k次。使用文本编辑器:打开CSV文件,并使用文本编辑器(如Notepad++、Sublime Text、Visual Studio Code等)来查看文件的字符编码格式。通常在编辑器的底部状态栏或设置中可以找到当前编码的显示。请注意,上述方法并非绝对准确,特别是当文件没有明确的编码标识时。因此,如果你发现CSV文件在不同的工具或方法中显示不同的编码格式,可能需要进行进一步的分析和判断,或者尝试使用不同的编码转换方法。该命令将输出文件的MIME类型和编码信息。使用命令行工具:在命令行中,你可以使用。_shell读取csv文件逐行处理
本文介绍了如何在Linux系统中升级gcc版本,以便更好地支持C++11及以上版本的新特性。通过升级gcc,可以提升编译器的功能和性能,获得更好的开发体验。详细的步骤和方法请参考原文链接。
文章浏览阅读4.4k次,点赞6次,收藏19次。Mosquitto是一个开源的MQTT消息代理服务器。MQTT是一个轻量级的、基于发布/订阅模式的消息传输协议。 mosquitto的安装使用比较简单,可以方便的来进行一些测试。_linux mosquitto
文章浏览阅读7.2k次,点赞2次,收藏12次。Linux中,用于根目录下有一个.ssh目录,保存了ssh相关的key和一些记录文件。_~/.ssh/
文章浏览阅读4.5k次,点赞5次,收藏18次。首先需要安装 snmp ,使用下面的命令进行安装安装完毕之后,使用下面的命令查看是否安装成功当命令行显示如图即为安装成功。_snmp工具