Linux 中 lsof 命令的 7 个示例
我想你一定曾经想过,是否有办法显示某个进程或用户打开的文件。幸运的是,这个问题的答案是 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.列出目录中所有打开的文件
如果您想知道某个目录中打开了哪些文件,可以使用带有 +D 选项的 lsof 命令。
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 命令一起使用时,它会变得更加有用。
希望您能从本文中学到一些新东西。如果您有任何问题或建议,请在下面发表评论。