Linux中的lsof命令

时间:2020-03-05 15:28:52  来源:igfitidea点击:

ls命令是“ list”的缩写。
lsof代表“列出打开的文件(List Open Files)”。
这就是它的作用,按进程,用户和进程ID列出打开的文件。

让我向我们展示lsof命令的一些最常见用法。

lsof命令示例

如果使用不带任何选项和参数的lsof命令,它将按系统中的所有进程列出所有打开的文件。

lsof

输出应如下所示:

COMMAND     PID   TID             USER   FD      TYPE             DEVICE  SIZE/OFF       NODE NAME
systemd       1                   root  cwd       DIR              252,1      4096          2 /
systemd       1                   root  rtd       DIR              252,1      4096          2 /
systemd       1                   root  txt       REG              252,1   1595792      17384 /lib/systemd/systemd
systemd       1                   root  mem       REG              252,1   1700792       2077 /lib/x86_64-linux-gnu/libm-2.27.so

输出大部分是自解释的,但我们可能仍然对FD和TYPE列感到疑惑。

FD表示文件描述符。
FD的一些常见值是:

  • cwd –当前工作目录
  • txt –文本文件
  • mem –内存映射文件
  • mmap –内存映射设备
  • NUMBER –实际的文件描述符。它还具有有关在哪个文件权限中打开的信息。

TYPE毋庸置疑。
它指定文件类型。
这里有些例子:

  • REG –常规文件
  • DIR –目录
  • CHR –特殊字符文件
  • FIFO –先进先出

如果我在Ubuntu服务器上运行lsof命令并使用wc命令计算行数,则结果如下。

lsof | wc -l
11432

系统中的各个进程打开了超过一万一千个文件。

不用担心lsof命令在调试中非常有用,因为我们可以看到哪些进程打开了哪些文件以及哪个进程打开了哪个文件。

如果我们不是以root用户身份登录,则lsof命令的输出将非常有限。
如果我们以非root用户身份登录,则最好使用sudo。

1.列出所有打开文件的过程

我们只需要指定文件的路径即可。

lsof <path_to_file>

2.列出用户打开的所有文件

这在多用户环境中非常方便。
我们可以通过以下方式列出某个用户打开的所有文件:

lsof -u <user_name>

我们还可以这样指定多个用户:

lsof -u user1, user2

或者像这样:

lsof -u user1 -u user2

3.列出目录中所有打开的文件

如果我们想在某个目录中打开过哪些文件,可以将lsof命令与+ D方法一起使用。

lsof +D <path_to_directory>

搜索是递归的。
因此,它将列出提到的目录及其所有子目录中的所有打开的文件。

4.按进程列出所有打开的文件

在这种情况下,我们需要知道进程ID(pid)。
如果知道进程ID,则可以使用lsof命令的-p选项查找由它打开的文件。

lsof -p <pid>

我们也可以指定多个进程ID。

lsof -p pid1, pid2, pid3

5.列出命令打开的所有文件

这在调试中特别有用。
假设我们想查看http守护程序使用了哪些文件,只需要指定命令名称(在我们的示例中为httpd)即可。

lsof -c <command>

6.查找由用户打开的命令和进程

我们可以使用–a选项将用户和命令等选项与进程组合在一起。
将其视为AND运算符。
这为我们提供了一个另外的过滤器,同时试图缩小搜索范围。

lsof -a -u user_name -c command_name

7.使用lsof命令列出网络连接和端口

我们也可以使用lsof命令查找打开的端口或者查找哪个进程正在使用端口。

我们可以使用-i选项归档所有打开的端口:

lsof -i

输出可能如下所示:

lsof -i
 COMMAND     PID            USER   FD   TYPE   DEVICE SIZE/OFF NODE NAME
 sshd        920            root    3u  IPv4    20507      0t0  TCP *:ssh (LISTEN)
 sshd        920            root    4u  IPv6    20535      0t0  TCP *:ssh (LISTEN)
 docker-pr  1163            root    4u  IPv6    21687      0t0  TCP *:https (LISTEN)
 docker-pr  1175            root    4u  IPv6    21717      0t0  TCP *:http (LISTEN)
 sshd       7528            root    3u  IPv4 39506588      0t0  TCP testing:ssh->212.91.91.19:58904 (ESTABLISHED)
 systemd-r 10993 systemd-resolve   12u  IPv4 20901990      0t0  UDP localhost:domain 
 systemd-r 10993 systemd-resolve   13u  IPv4 20901991      0t0  TCP localhost:domain (LISTEN)

我们也可以指定网络连接类型。
例如,要列出所有打开的TCP端口,可以使用:

lsof -i tcp

要查找哪个进程正在使用特定端口,可以提供端口号:

lsof -i :<port_number>

温馨提示:对lsof使用否定运算符(^)

使用lsof命令时,可以使用否定运算符排除用户或者进程。

例如,我们要列出由root以外的用户打开的所有文件,请按以下方式使用它:

lsof -u ^root

当与grep命令一起使用时,lsof命令将变得更加有用。