这里到底发生了什么?
root@bob-p7-1298c:/# ls -l /tmp/report.csv && lsof | grep "report.csv"
-rw-r--r-- 1 mysql mysql 1430 Dec 4 12:34 /tmp/report.csv
lsof: WARNING: can't stat() fuse.gvfsd-fuse file system /run/user/1000/gvfs
Output information may be incomplete.
答案1
FUSE及其访问权限
lsof
默认情况下检查所有已安装的文件系统,包括保险丝- 在 Linux 中具有特殊访问权限的用户空间中实现的文件系统。
正如你所看到的在 Ask Ubuntu 上回答已安装的重力加速度传感器文件系统(FUSE 的特例)通常只能由安装它的用户( 的所有者gvfsd-fuse
)访问。甚至root
无法访问。要覆盖此限制,可以使用安装选项allow_root
和allow_other
。该选项还必须在 FUSE 守护程序中启用,例如本节中所述回答...但就您而言,您不需要(也不应该)更改访问权限。
从 lsof 中排除文件系统
在您的情况下,lsof
不需要检查 GVFS 文件系统,因此您可以stat()
使用以下选项排除对它们的调用-e
(或者您可以忽略警告):
lsof -e /run/user/1000/gvfs
通过 lsof 检查某些文件
您正在使用lsof
获取有关系统上运行的所有进程的信息,然后才使用 过滤完整的输出grep
。如果您只想检查某些文件并且相关进程使用该-f
选项而不直接跟随其值,则在“选项结束”分隔符之后指定文件列表--
。这会快得多。
lsof -e /run/user/1000/gvfs -f -- /tmp/report.csv
通用解决方案
要排除所有stat()
失败的已挂载文件系统,您可以运行如下命令(在 中bash
):
x=(); for a in $(mount | cut -d' ' -f3); do test -e "$a" || x+=("-e$a"); done
lsof "${x[@]}" -f -- /tmp/report.csv
或者一定要使用stat()
(test -e
可以以不同的方式实现):
x=(); for a in $(mount | cut -d' ' -f3); do stat --printf= "$a" 2>/dev/null || x+=("-e$a"); done
答案2
lsof
总是尝试获取有关所有文件系统的一些基本信息,即使参数碰巧暗示特定文件系统不会产生任何结果。如果它无法访问文件系统(具体来说,stat
如消息所述,无法调用其安装点),它会抱怨。
作为 root,您通常有权访问文件系统。然而,由于内部运作保险丝,root 不会自动拥有 FUSE 文件系统的所有权限。这不是一个安全功能(root 可以成为拥有文件系统的用户并以这种方式进行访问),这是一个技术限制。
GVFS-FUSE 是一个 FUSE 接口重力加速度传感器,这是一种允许 Gnome 应用程序访问由 Gnome 插件实现的虚拟文件系统的机制:GVFS 授予非 Gnome 应用程序通过常规文件系统接口访问这些虚拟文件系统的权限。