如何使用Linux lsof命令

如果Linux中的所有东西都是一个文件,那么它一定不仅仅是硬盘上的文件。本教程将向您展示如何使用lsof查看作为文件处理的所有其他设备和进程。

在Linux上,一切都是一个文件

经常被引用的一句话,Linux中的一切都是一个文件,这在某种程度上是正确的。文件是字节的集合。当它们被读入程序或发送到打印机时,它们似乎会生成字节流。当它们被写入时,它们接受字节流。

许多其他系统组件接受或生成字节流,例如键盘、套接字连接、打印机和通信进程。因为它们接受、生成或接受并生成字节流,所以可以在非常低的级别上处理这些设备,就像它们是文件一样。

这种设计理念简化了Unix操作系统的实现。这意味着可以创建一小组处理程序、工具和API来处理各种不同的资源。

驻留在硬盘上的数据和程序文件是普通的旧文件系统文件。我们可以使用ls命令列出它们并查找有关它们的一些详细信息。

我们如何了解所有其他被视为文件的进程和设备?我们使用lsof命令。这将列出系统中打开的文件。也就是说,它列出了正在处理的所有内容,就好像它是一个文件一样。

相关:在Linux中“一切都是文件”是什么意思?

lsof命令

lsof可以报告的许多进程或设备属于root或由root启动,因此您需要将sudo命令与lsof一起使用。

因为这个列表将非常长,我们将通过较少的管道将其传递出去。

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)之外,没有人(甚至根用户)可以访问这些文件系统中的任何一个。您可以忽略此警告。

lsof的输出非常广泛。最左边的列是:

最右侧的列是:

lsof列

并非所有列都适用于每种类型的打开文件。它们中的一些是空白的,这是正常的。

命令:输入与打开文件的进程相关联的命令名称。 PID:打开文件的进程的进程标识号。 TID:任务(线程)标识号。空栏表示它不是任务;它是进程。 User:进程所属用户的用户ID或名称,或者/proc中拥有目录的人员的用户ID或登录名,lsof在/proc中查找有关进程的信息。 fd:显示文件的文件描述符。文件描述符如下所述。 类型:文件关联的节点类型,备注类型如下。 Device:包含特殊字符、块特殊、常规、目录或NFS文件的设备编号(用逗号分隔),或包含标识该文件的内核引用地址。它还可能显示Linux AX.25套接字设备的基本地址或设备名称。 Size/Off:显示文件的大小或文件偏移量(以字节为单位)。 节点:显示本地文件的索引节点号,或服务器主机中NFS文件的索引节点号,或互联网协议类型。它可能会显示流的STR,或者Linux AX.25套接字设备的IRQ或inode编号。 名称:显示文件所在的挂载点和文件系统的名称。

FD列

fd列中的文件描述符可以是众多选项之一;手册页将列出所有选项。

FD列条目可以由三部分组成:文件描述符、模式字符和锁定字符。一些常见的文件描述符包括:

CWD:当前工作目录。 错误:FD信息错误(参见名称栏)。 ltx:共享库文本(代码和数据)。 M86:DOS合并映射文件。 MEM:内存映射文件。 mmap:内存映射设备。 pd:父目录。 RTD:根目录。 txt:程序文本(代码和数据)。 一个数字,表示文件描述符。

模式字符可以是以下字符之一:

R:读取访问权限。 W:写访问权限。 U:读写访问权限。 ‘’:如果模式未知且没有锁定字符,则为空格字符。 -:模式未知,并且存在锁定字符。

锁定字符可以是以下之一:

R:文件部分上的读取锁定。 R:对整个文件的读锁定。 W:对文件的一部分进行写锁定。 W:对整个文件进行写锁定。 U:任意长度的读写锁。 U:未知的锁类型。 ‘’:空格字符。没有锁。

TYPE列

TYPE列中可能会出现70多个条目。您将看到的一些常见条目包括:

REG:常规文件系统文件。 dir:目录。 先进先出:先进先出。 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登录而打开的文件。

排除用户打开的文件

要排除用户已打开的文件,请使用^2运算符。将用户从列表中排除可以更容易地找到您感兴趣的信息。您必须像以前一样使用-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(AND)选项。这意味着将只列出与第一个搜索词和第二个搜索词匹配的文件,依此类推。

让我们再试一次,然后使用-a选项。

sudo lsof -u mary -c ssh -a

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

自动刷新显示器

我们可以使用+|-r(重复)选项将lsof置于重复模式。Repeat选项有两种应用方式,+r或-r。我们还必须添加刷新显示前希望lsof等待的秒数。

使用任一格式的REPEAT选项都会使lsof照常显示结果,但它会在显示的底部添加一条虚线。它等待命令行上提供的秒数,然后用一组新的结果刷新显示。

使用-r选项时,此操作将持续到您按Ctrl+C。使用+r格式时,此操作将继续,直到没有要显示的结果或您按Ctrl+C。

sudo lsof -u mary -c ssh -a -r5

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

显示与Internet连接关联的文件

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

lsof -i

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

按进程ID显示与Internet连接关联的文件

要查看通过与特定进程ID关联的Internet连接打开的文件,请添加-p选项和-a选项。

在这里,我们正在查找通过Internet或网络连接、ID为606的进程打开的文件。

sudo lsof -i -a -p 606

将显示由进程ID 606打开的与互联网或网络连接相关联的所有文件。

显示与Internet连接和命令关联的文件

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

lsof -i -a -c ssh

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

显示与Internet连接和端口关联的文件

我们可以对特定端口上通过互联网或网络连接打开的文件进行lsof报告。为此,我们使用:字符后跟端口号。

在这里,我们要求lsof列出已通过使用端口22的网络或Internet连接打开的文件。

lsof -i :22

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

显示与Internet连接和协议关联的文件

我们可以要求lsof显示已由与使用特定协议的网络和Internet连接相关联的进程打开的文件。我们可以从TCP、UDP和SMTP中选择。让我们使用TCP协议,看看我们能得到什么。

sudo lsof -i tcp

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

我们只触及了皮毛

在Llsof的一些常见用例中,这是一个很好的基础,但还有更多的原因。根据手册页超过2800行的长度可以判断还能增加多少。

lsof命令可用于深入打开文件和伪文件的层次。我们提供了一张草图,地图册在手册页。

相关文章