Linux 中的 lsof 命令:7 个实际示例
本文教您如何在 Linux 中使用 lsof 命令列出用户或进程打开的文件。ufeff
我想在某个时候您想知道是否有一种方法可以显示进程或用户打开的文件。好消息是这个问题的答案是 lsof 命令。
您可能已经知道 ls 命令是“list”的缩写。 lsof 代表“列出打开的文件”。这正是它的作用,按进程、用户和进程 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——先进先出
相信我。您不会想在没有任何参数的情况下运行 lsof 命令。
我为什么这么说呢?因为它会开始用数千个结果淹没您的屏幕。
如果我在 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
当将 lsof 命令与 grep 命令一起使用时,它会变得更加有用。
我希望您从这篇文章中学到了新的东西。如果您有疑问或建议,请在下方留言。