深入解析 Linux lsof 命令:轻松识别系统中打开的文件

链接:https://bbs.huaweicloud.com/blogs/364149

4dbab04fc84f301c59142f6cc238d085.png

【摘要】 它是一个命令行实用程序,用于列出有关由各种进程打开的文件的信息。在 Linux 中,一切都是文件(管道、套接字、目录、设备等)。因此,通过使用 lsof,您可以获得有关任何已打开文件的信息

lsof 代表列出打开的文件。

如果您将 lsof 命令视为“ls + of”,则很容易记住它,其中 ls 代表列表,of 代表打开的文件。

它是一个命令行实用程序,用于列出有关由各种进程打开的文件的信息。在 Linux 中,一切都是文件(管道、套接字、目录、设备等)。因此,通过使用 lsof,您可以获得有关任何已打开文件的信息。


一、lsof简介

只需键入 lsof 即可提供属于所有活动进程的所有打开文件的列表。

# lsof

COMMAND  PID       USER   FD      TYPE     DEVICE  SIZE/OFF       NODE NAME
init       1       root  cwd       DIR        8,1      4096          2 /
init       1       root  txt       REG        8,1    124704     917562 /sbin/init
init       1       root    0u      CHR        1,3       0t0       4369 /dev/null
init       1       root    1u      CHR        1,3       0t0       4369 /dev/null
init       1       root    2u      CHR        1,3       0t0       4369 /dev/null
init       1       root    3r     FIFO        0,8       0t0       6323 pipe
...

默认情况下,每行显示一个文件。大多数列都是不言自明的。我们将解释几个神秘的列(FD 和 TYPE)的细节。

FD——代表文件描述符。FD的一些值是,

  • cwd - 当前工作目录

  • txt - 文本文件

  • mem – 内存映射文件

  • mmap – 内存映射设备

  • NUMBER – 表示实际的文件描述符。数字后面的字符,即'1u',代表文件打开的模式。r 读,w 写,u 读和写。

TYPE – 指定文件的类型。类型的一些值是,


  • REG – 常规文件

  • DIR——目录

  • FIFO——先进先出

  • CHR——字符特殊文件

2.列出打开特定文件的进程

通过提供文件名作为参数,您可以仅列出打开特定文件的进程。

# lsof /var/log/syslog

COMMAND  PID   USER   FD   TYPE DEVICE SIZE/OFF   NODE NAME
rsyslogd 488 syslog    1w   REG    8,1     1151 268940 /var/log/syslog

3.列出目录下打开的文件

您可以使用“+D”选项列出在指定目录下打开文件的进程。+D 也将递归子目录。如果您不希望 lsof 递归,请使用 '+d' 选项。

# lsof +D /var/log/

COMMAND   PID   USER  FD   TYPE DEVICE SIZE/OFF   NODE NAME
rsyslogd  488 syslog   1w   REG    8,1     1151 268940 /var/log/syslog
rsyslogd  488 syslog   2w   REG    8,1     2405 269616 /var/log/auth.log
console-k 144   root   9w   REG    8,1    10871 269369 /var/log/ConsoleKit/history

4.根据进程名列出打开的文件

您可以使用“-c”选项列出以字符串开头的进程名称打开的文件。-c 后跟进程名称将列出以该进程名称开头的进程打开的文件。您可以在单个命令行上提供多个 -c 开关。

# lsof -c ssh -c init

COMMAND    PID   USER   FD   TYPE DEVICE SIZE/OFF   NODE NAME
init         1       root  txt    REG        8,1   124704  917562 /sbin/init
init         1       root  mem    REG        8,1  1434180 1442625 /lib/i386-linux-gnu/libc-2.13.so
init         1       root  mem    REG        8,1    30684 1442694 /lib/i386-linux-gnu/librt-2.13.so
...
ssh-agent 1528 lakshmanan    1u   CHR        1,3      0t0    4369 /dev/null
ssh-agent 1528 lakshmanan    2u   CHR        1,3      0t0    4369 /dev/null
ssh-agent 1528 lakshmanan    3u  unix 0xdf70e240      0t0   10464 /tmp/ssh-sUymKXxw1495/agent.1495

5. 使用挂载点列出进程

有时当我们尝试卸载目录时,系统会提示“设备或资源忙”错误。所以我们需要找出所有使用挂载点的进程并杀死这些进程以卸载目录。通过使用 lsof 我们可以找到这些进程。

# lsof /home

以下也将起作用。

# lsof +D /home/

6.列出特定用户打开的文件

要查找特定用户打开的文件列表,请使用“-u”选项。

# lsof -u lakshmanan

COMMAND    PID       USER   FD   TYPE     DEVICE SIZE/OFF       NODE NAME
update-no 1892 lakshmanan   20r  FIFO        0,8      0t0      14536 pipe
update-no 1892 lakshmanan   21w  FIFO        0,8      0t0      14536 pipe
bash      1995 lakshmanan  cwd    DIR        8,1     4096     393218 /home/lakshmanan

有时您可能希望列出所有用户打开的文件,预计有 1 或 2 个。在这种情况下,您可以使用 '^' 仅排除特定用户,如下所示

# lsof -u ^lakshmanan

COMMAND    PID       USER   FD      TYPE     DEVICE  SIZE/OFF       NODE NAME
rtkit-dae 1380      rtkit    7u     0000        0,9         0       4360 anon_inode
udisks-da 1584       root  cwd       DIR        8,1      4096          2 /

上面的命令列出了所有用户打开的所有文件,除了用户'lakshmanan'。

7. 按特定进程列出所有打开的文件

您可以使用“-p”选项列出特定进程打开的所有文件。有时获取有关特定流程的更多信息会很有帮助。

# lsof -p 1753

COMMAND  PID       USER   FD   TYPE DEVICE SIZE/OFF    NODE NAME
bash    1753 lakshmanan  cwd    DIR    8,1     4096  393571 /home/lakshmanan/test.txt
bash    1753 lakshmanan  rtd    DIR    8,1     4096       2 /
bash    1753 lakshmanan  255u   CHR  136,0      0t0       3 /dev/pts/0
...

8.kill属于特定用户的所有进程

当你想kill所有由特定用户打开文件的进程时,你可以使用'-t'选项列出只输出进程的进程id,并将其传递给kill,如下所示

# kill -9 `lsof -t -u lakshmanan`

上述命令将kill属于用户“lakshmanan”的所有进程,该用户已打开文件。

同样,您也可以通过多种方式使用“-t”。例如,列出打开 /var/log/syslog 的进程的进程 ID 可以通过

# lsof -t /var/log/syslog

489

9. 使用 OR/AND 组合更多列表选项

默认情况下,当您在 lsof 中使用多个列表选项时,它们将被 ORed。例如,

# lsof -u lakshmanan -c init

COMMAND    PID       USER   FD   TYPE     DEVICE SIZE/OFF       NODE NAME
init         1       root  cwd    DIR        8,1     4096          2 /
init         1       root  txt    REG        8,1   124704     917562 /sbin/init
bash      1995 lakshmanan    2u   CHR      136,2      0t0          5 /dev/pts/2
bash      1995 lakshmanan  255u   CHR      136,2      0t0          5 /dev/pts/2
...

上面的命令使用两个列表选项,“-u”和“-c”。因此该命令将列出属于用户“lakshmanan”的进程以及以“init”开头的进程名称。

但是当你想列出一个进程属于用户'lakshmanan'并且进程名称以'init'开头时,你可以使用'-a'选项。

# lsof -u lakshmanan -c init -a

上面的命令不会输出任何东西,因为不存在属于用户 'lakshmanan' 的名为 'init' 的进程。

10.以重复模式执行lsof

lsof 还支持重复模式。它将首先根据给定的参数列出文件,并延迟指定的秒数,然后再次根据给定的参数列出文件。它可以被信号中断。

可以使用“-r”或“+r”启用重复模式。如果然后使用'+r',则重复模式将在没有找到打开的文件时结束。'-r' 将继续列出、延迟、列出直到给出中断,而不管文件是否打开。

每个循环输出将使用 '=======' 分隔。您还可以将时间延迟指定为 '-r' | '+r'。

# lsof -u lakshmanan -c init -a -r5

=======
=======
COMMAND   PID       USER   FD   TYPE DEVICE SIZE/OFF    NODE NAME
inita.sh 2971 lakshmanan  cwd    DIR    8,1     4096  393218 /home/lakshmanan
inita.sh 2971 lakshmanan  rtd    DIR    8,1     4096       2 /
inita.sh 2971 lakshmanan  txt    REG    8,1    83848  524315 /bin/dash
inita.sh 2971 lakshmanan  mem    REG    8,1  1434180 1442625 /lib/i386-linux-gnu/libc-2.13.so
inita.sh 2971 lakshmanan  mem    REG    8,1   117960 1442612 /lib/i386-linux-gnu/ld-2.13.so
inita.sh 2971 lakshmanan    0u   CHR  136,4      0t0       7 /dev/pts/4
inita.sh 2971 lakshmanan    1u   CHR  136,4      0t0       7 /dev/pts/4
inita.sh 2971 lakshmanan    2u   CHR  136,4      0t0       7 /dev/pts/4
inita.sh 2971 lakshmanan   10r   REG    8,1       20  393578 /home/lakshmanan/inita.sh
=======

在上面的输出中,前 5 秒没有输出。之后启动名为“inita.sh”的脚本,并列出输出。

寻找网络连接

网络连接也是文件。因此我们可以使用 lsof 找到有关它们的信息。

11.列出所有网络连接

您可以使用“-i”选项列出所有打开的网络连接。

# lsof -i

COMMAND    PID  USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
avahi-dae  515 avahi   13u  IPv4   6848      0t0  UDP *:mdns
avahi-dae  515 avahi   16u  IPv6   6851      0t0  UDP *:52060
cupsd     1075  root    5u  IPv6  22512      0t0  TCP ip6-localhost:ipp (LISTEN)

您还可以使用“-i4”或“-i6”分别仅列出“IPV4”或“ IPV6 ”。


12.列出特定进程正在使用的所有网络文件

您可以列出进程正在使用的所有网络文件,如下所示

# lsof -i -a -p 234

您还可以使用以下

# lsof -i -a -c ssh

上面的命令会列出以 ssh 开头的进程打开的网络文件。


13. 列出正在监听特定端口的进程

您可以使用 '-i' 和 ':' 列出正在侦听特定端口的进程,如下所示

# lsof -i :25

COMMAND  PID        USER   FD   TYPE DEVICE SIZE NODE NAME
exim4   2541 Debian-exim    3u  IPv4   8677       TCP localhost:smtp (LISTEN)


14. 列出所有 TCP 或 UDP 连接

您可以通过使用“-i”指定协议来列出所有 TCP 或 UDP 连接。

# lsof -i tcp; lsof -i udp;


15. 列出所有网络文件系统 (NFS) 文件

您可以使用“-N”选项列出所有 NFS 文件。以下 lsof 命令将列出用户“lakshmanan”使用的所有 NFS 文件。

# lsof -N -u lakshmanaan -a

cb29a70a113497123ca713e3aa9b69bb.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值