如何使用 Linux lsof 命令

如果 Linux 中的一切都是文件,那么它所包含的肯定不仅仅是硬盘上的文件。本教程将向您展示如何使用 lsof
查看作为文件处理的所有其他设备和进程。
在 Linux 上,一切皆文件
Linux 中的一切都是一个文件这句经常被引用的短语有点真实。文件是字节的集合。当它们被读入程序或被发送到打印机时,它们似乎生成字节流。当它们被写入时,它们接受字节流。
许多其他系统组件接受或生成字节流,例如键盘、套接字连接、打印机和通信进程。因为它们接受、生成或接受并生成字节流,所以可以在非常低的级别上处理这些设备,就好像它们是文件一样。
这种设计理念简化了 Unix 操作系统的实现。这意味着可以创建一小组处理程序、工具和 API 来处理范围广泛的不同资源。
驻留在硬盘上的数据和程序文件是普通的旧文件系统文件。我们可以使用 ls
命令列出它们并找出有关它们的一些详细信息。
我们如何找出所有其他被视为文件的进程和设备?我们使用 lsof
命令。这列出了系统中打开的文件。也就是说,它列出了正在处理的任何内容,就好像它是一个文件一样。
lsof 命令
lsof
可以报告的许多进程或设备属于 root 或由 root 启动,因此您需要将 sudo
命令与 lsof一起使用代码>。
因为这个列表会很长,所以我们将通过 less
来处理它。
sudo lsof | less

在 lsof
输出出现之前,GNOME 用户可能会在终端窗口中看到一条警告消息。
lsof: WARNING: can't stat() fuse.gvfsd-fuse file system /run/user/1000/gvfs
Output information may be incomplete.
lsof
尝试处理所有挂载的文件系统。出现此警告消息是因为 lsof
遇到了 GNOME 虚拟文件系统 (GVFS)。这是用户空间文件系统 (FUSE) 的特例。它充当 GNOME、其 API 和内核之间的桥梁。除了安装它的所有者(在本例中为 GNOME)之外,任何人(甚至 root 用户)都不能访问这些文件系统之一。您可以忽略此警告。
lsof
的输出非常宽。最左边的列是:

最右边的列是:

lsof 列
并非所有列都适用于所有类型的打开文件。其中一些为空白是正常的。
- 命令:与打开文件的进程关联的命令的名称。
- PID:打开文件的进程的进程标识号。
- TID:任务(线程)标识号。空白列表示它不是任务;这是一个过程。
- 用户:进程所属用户的用户 ID 或名称,或者在
/proc
中拥有目录的人的用户 ID 或登录名,其中lsof
查找有关进程的信息。 - FD:显示文件的文件描述符。文件描述符如下所述。
- 类型:与文件关联的节点类型。注释类型如下所述。
- 设备:包含特殊字符、特殊块、常规、目录或 NFS 文件的设备编号(以逗号分隔),或标识文件的内核引用地址。它还可能显示 Linux AX.25 套接字设备的基地址或设备名称。
- Size/Off:显示文件大小或文件偏移量(以字节为单位)。
- 节点:显示本地文件的节点号,或服务器主机中 NFS 文件的索引节点号,或互联网协议类型。它可能会显示流的 STR 或 IRQ 或 Linux AX.25 套接字设备的索引节点号。
- 名称:显示挂载点的名称和文件所在的文件系统。
FD专栏
FD 列中的文件描述符可以是许多选项之一;手册页列出了所有这些。
FD列项可以由三部分组成:文件描述符、模式字符和锁定字符。一些常见的文件描述符是:
- cwd:当前工作目录。
- err:FD 信息错误(见 NAME 列)。
- ltx:共享库文本(代码和数据)。
- m86:DOS 合并映射文件。
- mem:内存映射文件。
- mmap:内存映射设备。
- pd:父目录。
- rtd:根目录。
- txt:程序文本(代码和数据)
- 一个数字,代表一个文件描述符。
模式字符可以是以下之一:
- r:读取权限。
- w:写入权限。
- u:读取和写入权限。
- ‘ ‘:一个空格字符,如果模式未知且没有锁定字符。
- -:模式未知,有一个锁定字符。
锁定字符可以是以下之一:
- r:对文件的一部分进行读取锁定。
- R:读取整个文件的锁。
- w:对文件的一部分写锁。
- W:对整个文件写锁。
- u:任意长度的读写锁。
- U:未知锁类型。
- ‘ ‘:一个空格字符。没有锁。
类型列
TYPE 列中可能会出现 70 多个条目。您将看到的一些常见条目是:
- REG:常规文件系统文件。
- DIR:目录。
- FIFO:先进先出。
- CHR:字符特殊文件。
- BLK:阻止特殊文件。
- INET:互联网套接字。
- unix:UNIX 域套接字
查看打开文件的进程
要查看已打开某个文件的进程,请将文件名作为参数提供给 lsof
。例如,要查看已打开 kern.log
文件的进程,请使用以下命令:
sudo lsof /var/log/kern.log

lsof
通过显示由用户 syslog
启动的单个进程 rsyslogd
进行响应。

查看从目录中打开的所有文件
要查看从目录中打开的文件以及打开它们的进程,请将目录作为参数传递给 lsof
。您必须使用 +D
(目录)选项。
要查看在 /var/log/
目录中打开的所有文件,请使用以下命令:
sudo lsof +D /var/log/

lsof
以该目录中所有打开文件的列表作为响应。

要查看从 /home
目录打开的所有文件,请使用以下命令:
sudo lsof +D /home

显示从 /home
目录打开的文件。请注意,某些列中的描述越短,整个列表越窄。

列出进程打开的文件
要查看特定进程已打开的文件,请使用 -c
(命令)选项。请注意,您可以一次向 lsof
提供多个搜索词。
sudo lsof -c ssh -c init

lsof
提供已被命令行上提供的任一进程打开的文件列表。

查看用户打开的文件
要将显示限制为特定用户已打开的文件,请使用 -u
(用户)选项。在此示例中,我们将查看由代表 Mary 拥有或启动的进程打开的文件。
sudo lsof -u mary

列出的所有文件都是代表用户 Mary 打开的。这包括由桌面环境打开的文件,例如,或仅仅由于 Mary 登录而打开的文件。

排除用户打开的文件
要排除用户打开的文件,请使用 ^
运算符。从列表中排除用户可以更容易地找到您感兴趣的信息。您必须像以前一样使用 -u
选项,并在开头添加 ^
字符用户的名字。
sudo lsof +D /home -u ^mary

这一次,/home
目录的列表不包括用户 Mary 打开的任何文件。

列出进程打开的文件
要列出已由特定进程打开的文件,请使用 -p
(进程)选项并提供进程 ID 作为参数。
sudo lsof - p 4610

已为您列出由您提供的进程 ID 打开的所有文件。

列出已打开文件的进程 ID
要查看已打开特定文件的进程的进程 ID,请使用 -t
(简洁)选项并在命令行上提供文件名。
sudo lsof -t /usr/share/mime/mime.cache

进程 ID 显示在一个简单的列表中。

使用 AND 和 OR 搜索
让我们列出用户 Mary 打开的与 SSH 进程相关的文件。我们知道我们可以在命令行中提供多个搜索项,所以这应该很容易。
sudo lsof -u mary -c ssh

现在让我们看看 lsof
的输出。那看起来不对;输出中有由 root 启动的条目。

那不是我们所期望的。发生了什么?
当您提供多个搜索词时,lsof
将返回与第一个搜索词或第二个搜索词匹配的任何文件,依此类推。换句话说,它执行 OR 搜索。
要使 lsof
执行 AND 搜索,请使用 -a
(和)选项。这意味着将列出的唯一文件将是匹配第一个搜索词、和第二个搜索词等的文件。
让我们再试一次并使用 -a
选项。
sudo lsof -u mary -c ssh -a

现在列表中的每个文件都是由 Mary 或代表 Mary 打开的,并且与 SSH 命令相关联。

自动刷新显示
我们可以使用 +|-r
(重复)选项将 lsof
置于重复模式。可以通过两种方式应用重复选项,+r
或 -r
。我们还必须添加我们希望 lsof
在刷新显示之前等待的秒数。
在任一格式中使用 repeat 选项都会使 lsof
像往常一样显示结果,但它会在显示的底部添加一条虚线。它等待命令行上提供的秒数,然后用一组新的结果刷新显示。
使用 -r
选项,这将继续,直到您按下 Ctrl+C。对于 +r
格式,它会继续显示,直到没有结果可显示,或者直到您按下 Ctrl+C。
sudo lsof -u mary -c ssh -a -r5

请注意清单底部的虚线。这会在刷新输出时分隔每个新的数据显示。

显示与 Internet 连接关联的文件
-i
(互联网)选项允许您查看由与网络和互联网连接关联的进程打开的文件。
lsof -i

显示通过网络和 Internet 连接打开的所有文件。

按进程 ID 显示与 Internet 连接关联的文件
要查看与特定进程 ID 关联的因特网连接打开的文件,请添加 -p
选项和 -a
选项。
在这里,我们正在寻找由 Internet 或网络连接打开的文件,由 ID 为 606 的进程打开。
sudo lsof -i -a -p 606

显示与因特网或网络连接关联的进程 ID 606 打开的所有文件。

显示与 Internet 连接和命令关联的文件
我们可以使用 -c
(命令)选项来查找特定进程打开的文件。要查找已通过与 ssh
进程关联的互联网或网络连接打开的文件,请使用以下命令:
lsof -i -a -c ssh

由于 ssh 进程打开的所有文件都列在输出中。

显示与 Internet 连接和端口关联的文件
我们可以让 lsof
报告在特定端口上通过 Internet 或网络连接打开的文件。为此,我们使用 :
字符后跟端口号。
在这里,我们要求 lsof
列出已使用端口 22 由网络或互联网连接打开的文件。
lsof -i :22

所有列出的文件都是由与端口 22(这是 SSH 连接的默认端口)关联的进程打开的。

显示与 Internet 连接和协议关联的文件
我们可以要求 lsof
显示与网络和 Internet 连接相关的进程打开的文件,这些文件使用特定的协议。我们可以选择 TCP、UDP 和 SMTP。让我们使用 TCP 协议,看看我们得到了什么。
sudo lsof -i tcp

列出的唯一文件是由使用 TCP 协议的进程打开的文件。

我们只触及了表面
这为 lsof
的一些常见用例打下了良好的基础,但除此之外还有很多其他用例。手册页超过 2,800 行的事实可以判断还有多少。
lsof
命令可用于更深入地钻探打开文件和伪文件的层。我们提供了示意图;地图集在手册页中。
Linux Commands | ||
Files | tar · pv · cat · tac · chmod · grep · diff · sed · ar · man · pushd · popd · fsck · testdisk · seq · fd · pandoc · cd · $PATH · awk · join · jq · fold · uniq · journalctl · tail · stat · ls · fstab · echo · less · chgrp · chown · rev · look · strings · type · rename · zip · unzip · mount · umount · install · fdisk · mkfs · rm · rmdir · rsync · df · gpg · vi · nano · mkdir · du · ln · patch · convert · rclone · shred · srm · scp · gzip · chattr · cut · find · umask · wc | |
Processes | alias · screen · top · nice · renice · progress · strace · systemd · tmux · chsh · history · at · batch · free · which · dmesg · chfn · usermod · ps · chroot · xargs · tty · pinky · lsof · vmstat · timeout · wall · yes · kill · sleep · sudo · su · time · groupadd · usermod · groups · lshw · shutdown · reboot · halt · poweroff · passwd · lscpu · crontab · date · bg · fg · pidof · nohup · pmap | |
Networking | netstat · ping · traceroute · ip · ss · whois · fail2ban · bmon · dig · finger · nmap · ftp · curl · wget · who · whoami · w · iptables · ssh-keygen · ufw · arping · firewalld |
RELATED: Best Linux Laptops for Developers and Enthusiasts