小智 42
要以跨平台方式列出所有打开的文件,我建议使用psutil.
#!/usr/bin/env python
import psutil
for proc in psutil.process_iter():
print proc.open_files()
Run Code Online (Sandbox Code Playgroud)
原始问题隐含地将操作限制为当前正在运行的进程,可以通过psutil的Process类访问该进程.
proc = psutil.Process()
print proc.open_files()
Run Code Online (Sandbox Code Playgroud)
最后,您需要使用具有相应权限的帐户运行代码才能访问此信息,否则您可能会看到AccessDenied错误.
Cla*_*diu 40
我最终将内置文件对象包装在程序的入口点.我发现我没有关闭我的记录器.
import io
import sys
import builtins
import traceback
from functools import wraps
def opener(old_open):
@wraps(old_open)
def tracking_open(*args, **kw):
file = old_open(*args, **kw)
old_close = file.close
@wraps(old_close)
def close():
old_close()
open_files.remove(file)
file.close = close
file.stack = traceback.extract_stack()
open_files.add(file)
return file
return tracking_open
def print_open_files():
print(f'### {len(open_files)} OPEN FILES: [{", ".join(f.name for f in open_files)}]', file=sys.stderr)
for file in open_files:
print(f'Open file {file.name}:\n{"".join(traceback.format_list(file.stack))}', file=sys.stderr)
open_files = set()
io.open = opener(io.open)
builtins.open = opener(builtins.open)
Run Code Online (Sandbox Code Playgroud)
Mik*_*one 23
在Linux上,您可以查看以下内容/proc/self/fd
:
$ ls -l /proc/self/fd/
total 0
lrwx------ 1 foo users 64 Jan 7 15:15 0 -> /dev/pts/3
lrwx------ 1 foo users 64 Jan 7 15:15 1 -> /dev/pts/3
lrwx------ 1 foo users 64 Jan 7 15:15 2 -> /dev/pts/3
lr-x------ 1 foo users 64 Jan 7 15:15 3 -> /proc/9527/fd
Run Code Online (Sandbox Code Playgroud)
sha*_*unc 14
虽然上面打开的解决方案对于自己的代码很有用,但我正在调试我的客户端到第三方库,包括一些c扩展代码,所以我需要一个更直接的方法.以下例程在darwin下工作,并且(我希望)其他类似unix的环境:
def get_open_fds():
'''
return the number of open file descriptors for current process
.. warning: will only work on UNIX-like os-es.
'''
import subprocess
import os
pid = os.getpid()
procs = subprocess.check_output(
[ "lsof", '-w', '-Ff', "-p", str( pid ) ] )
nprocs = len(
filter(
lambda s: s and s[ 0 ] == 'f' and s[1: ].isdigit(),
procs.split( '\n' ) )
)
return nprocs
Run Code Online (Sandbox Code Playgroud)
如果有人可以扩展到可移植到Windows,我将不胜感激.
如前所述,您可以在 Linux 上的/proc/self/fd 中列出 fds ,这是一种以编程方式列出它们的简单方法:
import os
import sys
import errno
def list_fds():
"""List process currently open FDs and their target """
if not sys.platform.startswith('linux'):
raise NotImplementedError('Unsupported platform: %s' % sys.platform)
ret = {}
base = '/proc/self/fd'
for num in os.listdir(base):
path = None
try:
path = os.readlink(os.path.join(base, num))
except OSError as err:
# Last FD is always the "listdir" one (which may be closed)
if err.errno != errno.ENOENT:
raise
ret[int(num)] = path
return ret
Run Code Online (Sandbox Code Playgroud)