快速了解Linux上的文件是否已打开?

时间:2012-07-10 10:31:54

标签: python linux

有没有快速的方法(即最小化答案时间)来确定文件是否在Linux上打开?

假设我有一个进程将一个文件写入一个目录,另一个进程读取这些文件一旦完成编写,后一个进程可以知道文件是否仍在写入通过前一个过程?

如果可能的话,基于Python的解决方案将是理想的。

注意:我知道我可以使用基于FIFO /队列的解决方案,但我正在寻找其他的东西。

11 个答案:

答案 0 :(得分:8)

您当然可以使用Linux的INOTIFY功能,但避免这种情况更安全:让编写过程创建文件(比如data.tmp),读取过程肯定会忽略这些文件。当作者完成时,它应该只为读者重命名文件(比如说.dat)。重命名操作保证不会产生误解。

答案 1 :(得分:4)

如果您知道写入过程的PID,在Linux中您只需查询/ proc / {PID} / fd /并查看其中一个链接是否指向您的某个文件。

你要做的是,扫描目录,归档fd 5(比如说)指向/var/data/whatever/file1.log的事实。然后将指向的文件存储到数组中。

此时如果文件名在数组中,则该进程正在使用它。

所以:

import os
# Here I use PID = 31824
path="/proc/%d/fd" % 31824
openfiles   = [ os.readlink("%s/%s" % (path, fname)) for fname in os.listdir(path) ]

if whatever in openfiles:
    # whatever is used by pid 31824.

答案 2 :(得分:1)

如果您可以更改“第一个”流程逻辑,那么简单的解决方案就是将数据写入临时文件,并在写完所有数据后重命名该文件。

答案 3 :(得分:1)

马上就会想到

lsof | grep filename

答案 4 :(得分:1)

您有多种选择:

  • Inotify是一项允许您监视文件操作的功能
  • 编写过程在完成编写后重命名文件
  • 程序fuser将让您查询文件是否正在使用
  • 了解编写器的PID可能会让您查询/proc/PID/fd打开文件描述符。

答案 5 :(得分:1)

如果您知道(或可以找到)写入过程的进程ID,则可以使用psutil库。 sudo pip install psutil获取图书馆。文档在这里:http://pythonhosted.org/psutil/

>>> import psutil
>>> import os
>>> p = psutil.Process(os.getpid())
>>> p.open_files()
[]
>>> f = open('foo.txt', 'w')
>>> p.open_files()
[openfile(path='/Users/mariaz/Downloads/foo.txt', fd=3)]

如果您无权访问写入过程,则需要以root身份运行lsof并自行解析输出。

答案 6 :(得分:1)

这是使用inotify的解决方案。在写入操作之后,您将收到关闭目录中每个文件的通知。

import os
import pyinotify

def Monitor(path):
    class PClose(pyinotify.ProcessEvent):
        def process_IN_CLOSE(self, event):
            f = event.name and os.path.join(event.path, event.name) or event.path
            print 'close event: ' + f

    wm = pyinotify.WatchManager()
    notifier = pyinotify.Notifier(wm, PClose())
    wm.add_watch(path, pyinotify.IN_CLOSE_WRITE)

    try:
        while 1:
            notifier.process_events()
            if notifier.check_events():
                notifier.read_events()
    except KeyboardInterrupt:
        notifier.stop()
        return

if __name__ == '__main__':
    path = "."
    Monitor(path)

但是,由于您是控制编写文件的过程的人,因此我会投票选出涉及流程之间某种通信的不同解决方案。

答案 7 :(得分:0)

您可以检查文件的修改时间,看看文件是否在一段时间内未被修改。由于文件可以在更新模式下打开并且可以随时修改,因此您无法100%确定它永远不会被修改。

答案 8 :(得分:0)

我会使用psutil(https://github.com/giampaolo/psutil),它还具有跨平台的优势,并提供许多其他有用的系统功能。

答案 9 :(得分:0)

您可以将 lsof 子流程

一起使用
(output,error) = subprocess.Popen("lsof #absolute_file_path").communicate()

答案 10 :(得分:0)

你可以使用fcntl模块,afaik,它有与C函数相同的fcntl函数,所以像fcntl(fd, F_GETFL)这样的东西可能有用,但我不确定。您是否可以通过在写入模式下打开来检查目标文件是否被阻止写入?