2

Linux でファイルが開いているかどうかを確認する簡単な方法 (回答までの時間を最小限に抑える方法) はありますか?

ディレクトリに大量のファイルを書き込むプロセスと、書き込みが終了したらそれらのファイルを読み取る別のプロセスがあるとします後者のプロセスは、ファイルがまだ前のプロセスによって書き込まれているかどうかを知ることができますか?

可能であれば、Python ベースのソリューションが理想的です。

注: FIFO / Queue ベースのソリューションを使用できることは理解していますが、他のソリューションを探しています。

4

11 に答える 11

10

もちろん、Linux の INOTIFY 機能を使用することもできますが、状況を回避する方が安全です。書き込みプロセスにファイル (data.tmp など) を作成させ、読み取りプロセスが確実に無視するようにします。ライターが終了したら、リーダー用にファイルの名前を変更するだけです (たとえば .dat に)。名前の変更操作により、誤解がないことが保証されます。

于 2012-07-10T10:35:53.947 に答える
4

書き込みプロセスの PID がわかっている場合、Linux では単純に /proc/{PID}/fd/ をクエリして、そこにあるリンクの 1 つがファイルの 1 つを指しているかどうかを確認できます。

あなたがすることは、ディレクトリをスキャンして、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.
于 2012-07-10T10:36:21.457 に答える
2

lsof | grep filenameすぐに思い浮かびます。

于 2012-07-10T10:38:39.973 に答える
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)

ただし、ファイルを書き込むプロセスを管理しているのはあなたなので、プロセス間の何らかの通信を含む別のソリューションに投票します。

于 2012-07-10T10:50:32.873 に答える
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)]

書き込みプロセスにアクセスできない場合は、ルートとしてlsofを実行し、出力を自分で解析する必要があります。

于 2012-07-10T10:45:25.927 に答える
1

私は psutil ( https://github.com/giampaolo/psutil ) を使用します。これもクロスプラットフォームであるという利点があり、他の多くの便利なシステム機能を提供します。

于 2012-07-10T10:36:35.163 に答える
1

「最初の」プロセスロジックを変更できる場合、簡単な解決策は、データを一時ファイルに書き込み、すべてのデータが書き込まれた後にファイルの名前を変更することです。

于 2012-07-10T10:36:40.443 に答える
1

さまざまなオプションを利用できます。

  • inotifyは、ファイル操作を監視できる機能です
  • 書き込みプロセスは、書き込みが終了したときにファイルの名前を変更します
  • プログラムフューザーを使用すると、ファイルが使用中かどうかを照会できます
  • ライターの PID がわかれば/proc/PID/fd、開いているファイル記述子を照会できる場合があります。
于 2012-07-10T10:41:11.860 に答える
0

fcntlモジュールafaikを使用できます。これには、C関数と同じfcntl関数があるため、次のようなものfcntl(fd, F_GETFL)が役立つ可能性がありますが、よくわかりません。ターゲットファイルを書き込みモードで開いて、書き込みがブロックされているかどうかを確認できますか?

于 2012-07-10T11:00:44.457 に答える
0

ファイルの変更時刻を確認して、一定期間変更されていないかどうかを確認できます。ファイルは更新モードで開いていつでも変更できるため、変更されないことを 100% 保証することはできません。

于 2012-07-10T10:36:01.687 に答える
0

サブプロセスでlsofを使用できます

(output,error) = subprocess.Popen("lsof #absolute_file_path").communicate()
于 2012-07-10T10:40:23.820 に答える