lsof命令指定用户时不检查指定目录

-1 投票
2 回答
1328 浏览
提问于 2025-04-17 15:48

我在写一个Python脚本,目的是使用lsof命令列出特定目录(我的主目录)下所有打开的文件,只显示唯一的条目。

我的脚本是这样的:

import os, sys, getpass
user = getpass.getuser()
cmd = "lsof -u " + user + " +d ~ | sort | uniq"
os.system(cmd)

这个脚本基本上能做到我想要的,它确实是针对当前本地用户执行lsof命令,但它没有在我指定的主目录下查找。相反,它是在根目录下执行lsof,列出了该用户在整个文件系统中的所有打开文件。不过,当我不加 -u user 这个选项时,它就能准确地在主目录下查找。我一直在研究为什么会这样,确实尝试过用 +d /home/+d ~/home/ 来替代单纯的 +d ~,但都没有成功,所以我有点困惑。如果能给点建议就太好了 :)

2 个回答

0

来自手册页的内容:

通常情况下,列出的选项是“或”的关系。也就是说,如果你使用了 -i 选项但没有指定地址,同时又使用了 -ufoo 选项,那么你会得到所有网络文件和属于用户“foo”的进程的文件的列表。

虽然有一些例外情况,但在你的情况中并不适用。

所以,-u me +d ~ 的意思是“所有我打开的文件或者在我的主目录中的文件”。

那么,如何实现你想要的呢?

可以使用 -a 选项来进行“与”的关系选择。比如说,如果你同时指定 -a、-U 和 -ufoo,就只会列出属于用户“foo”的 UNIX 套接字文件。

在这里加上一个 -a

cmd = "lsof -a -u " + user + " +d ~ | sort | uniq"

顺便说一下,通常情况下,你真的不想在 Python 中使用 os.system,这就是文档特别提到的原因:

subprocess 模块提供了更强大的功能来启动新进程并获取它们的结果;使用这个模块比使用这个函数更好。有关一些有用的示例,请查看 用 subprocess 模块替换旧函数部分。

而且,真的,为什么要用 sortuniq,而不是直接在 Python 中排序呢?或者,如果你只是想运行这个 shell 管道,而不想在 Python 中处理它,为什么一开始不直接用 bash 呢?

0

lsof 默认是用“或”的方式把选项组合在一起,如果你想用“和”的方式组合,可以试试加上 -a 这个标志。

撰写回答