如何在Linux中检查文件是否已打开?

10

事情是这样的,我想追踪一个用户是否试图打开共享账户上的文件。我正在寻找任何记录/技术,帮助我了解相关文件是否在运行时被打开。

我想创建一个脚本来监视文件是否已打开,如果是,则将其发送到特定电子邮件地址的警报。我考虑的文件是普通文件。

我尝试使用lsof | grep filename检查在gedit中是否打开了文件,但该命令没有返回任何内容。

实际上,我正在为一个宠物项目尝试这个,因此提出了这个问题。

4个回答

12

命令lsof -t 文件名显示了所有打开该特定文件的进程ID。 lsof -t 文件名 | wc -w可以告诉您当前正在访问该文件的进程数量。


2
我建议使用wc -l而不是wc -w,因为它适用于更多的情况,而且lsof不会在一行中放置多个文件名。 - Alexis Wilke

6
一个文件被读取到像 gedit 这样的编辑器中,并不意味着该文件仍然处于打开状态。编辑器很可能打开文件,读取其内容,然后关闭文件。编辑文件后,您可以选择覆盖现有文件或将其另存为另一个文件。

3

除了其他答案之外,您可以使用Linux特有的inotify(7)工具。

我理解您想要跟踪一个(或几个)特定的文件,具有固定的文件路径(实际上是给定的i-node)。例如,您希望在访问或修改/var/run/foobar时进行跟踪,并在发生这种情况时执行某些操作

特别地,您可能希望安装并使用incrond(8),并通过incrontab(5)进行配置。

如果您想要在访问或修改某个给定文件(在本地原生文件系统,例如Ext4、BTRS等,但不是NFS文件系统)时运行脚本,请使用inotifyincrond正是为此目的而设计的。

PS. 据我所知,inotify 对于远程网络文件(例如NFS文件系统,特别是当另一个NFS客户机正在修改文件时)效果不佳。

如果您喜欢的文件是源文件,您可能会对版本控制系统(如git)或构建系统(如GNU make)感兴趣;在某种程度上,这些工具与文件修改有关。

您还可以将特定的文件系统放置在某些FUSE文件系统中,并编写自己的FUSE守护程序。

如果您可以限制和修改访问文件的程序,您可能希望使用咨询性锁定,例如flock(2)lockf(3)
也许应该将文件中的数据放在某个数据库(例如SQLite或像PostGreSQLMongoDB这样的真正的数据库管理系统中)。ACID属性很重要....
注意,文件系统挂载选项可能非常重要。
你可能想使用stat(1)命令。 如果不了解真实用例和动机,帮助起来会比较困难。你应该避免一些XY问题 也许工作流程有误(多个用户共享一个可写文件),你应该以其他方式解决整体问题。对于一个小型项目,我至少建议使用一些咨询锁,并且仅通过您自己的程序(可能是setuid)使用flock来访问和修改信息(这不包括像geditcat这样的普通编辑器或命令)。但是,您隐含的用例似乎非常适合DBMS方法(数据库不必包含大量数据,它可能很小),或者像GDBM库这样的索引锁定文件进行处理。

请记住,在POSIX系统和Linux上,多个进程可以同时访问(甚至修改)同一个文件(除非您使用某些锁定或同步方法)。

阅读《高级Linux编程》这本书(免费提供)可以让您有一个更广泛的视角(但它没有提到在该书写作之后出现的inotify)。

1
您提供的《Advanced Linux Programming》书籍链接已失效。 - Alexis Wilke

0

你可以使用ls -lrt命令,在shell中显示最后的读写操作。然后你就可以得出文件是否被打开的结论。确保你在正确的目录下。


2
"ls -lrt" 根据修改时间戳进行排序。如果您的文件系统支持它(在Linux中通常是这样),您还可以使用 "ls -lrt --time=atime" 查看文件上次访问的时间。 - Henrik Carlqvist

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接