链接:https://bbs.huaweicloud.com/blogs/364149
【摘要】 它是一个命令行实用程序,用于列出有关由各种进程打开的文件的信息。在 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