Skip to content

Instantly share code, notes, and snippets.

@lebedov
Last active January 24, 2024 02:09
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save lebedov/b0144d07d3bec93c5d14 to your computer and use it in GitHub Desktop.
Save lebedov/b0144d07d3bec93c5d14 to your computer and use it in GitHub Desktop.
Python functions for finding open files and PIDs that have opened a file.
#!/usr/bin/env python
"""
Python functions for finding open files and PIDs that have opened a file.
"""
import numbers
import subprocess
try:
from subprocess import DEVNULL
except ImportError:
import os
DEVNULL = open(os.devnull, 'wb')
def get_open_files(*pids):
"""
Find files opened by specified process ID(s).
Parameters
----------
pids : list of int
Process IDs.
Returns
-------
files : list of str
Open file names.
"""
for pid in pids:
if not isinstance(pid, numbers.Integral):
raise ValueError('invalid PID')
files = set()
for pid in pids:
try:
out = subprocess.check_output(['lsof', '-wXFn', '+p', str(pid)],
stderr=DEVNULL)
except:
pass
else:
lines = out.strip().split('\n')
for line in lines:
# Skip sockets, pipes, etc.:
if line.startswith('n') and line[1] == '/':
files.add(line[1:])
return list(files)
def get_pids_open(*files):
"""
Find processes with open handles for the specified file(s).
Parameters
----------
files : list of str
File paths.
Returns
-------
pids : list of int
Process IDs with open handles to the specified files.
"""
for f in files:
if not isinstance(f, basestring):
raise ValueError('invalid file name %s' % f)
pids = set()
try:
out = subprocess.check_output(['lsof', '+wt']+list(files),
stderr=DEVNULL)
except Exception as e:
out = str(e.output)
if not out.strip():
return []
lines = out.strip().split('\n')
for line in lines:
pids.add(int(line))
return list(pids)
@blzzua
Copy link

blzzua commented Nov 10, 2021

python3-fix for get_pids_open

def get_pids_open(*files):
    """
    Find processes with open handles for the specified file(s).

    Parameters
    ----------
    files : list of str
        File paths.

    Returns
    -------
    pids : list of int
        Process IDs with open handles to the specified files.
    """

    for f in files:
        if not isinstance(f, str):
            raise ValueError('invalid file name %s' % f)
    pids = set()
    try:
        out = subprocess.check_output(['lsof', '+wt']+list(files),
                stderr=DEVNULL).decode('utf8')
    except Exception as e:
        out = e.output.decode('utf8')
    if not out.strip():
        return []
    lines = out.strip().split('\n')
    for line in lines:
        pids.add(int(line))
    return list(pids)

@Aman0509
Copy link

That was helpful!
Can you also add OS independent version of function 'get_pids_open'?

@lebedov
Copy link
Author

lebedov commented Jul 12, 2022

@Aman0509 See https://psutil.readthedocs.io for a cross-platform approach.

Copy link

ghost commented Apr 5, 2023

As for a cross platform solution, this is what I used:

import psutil

file = "/home/username/.bashrc" # some file

for pid in psutil.process_iter():
    try:
        for opened_file in pid.open_files():

            if file == opened_file.path:
                # do something here

                # and stop
                break
    except psutil.AccessDenied:
        continue

This uses the psutil module

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment