Linux - 如何跟踪进程访问的所有文件?

问题描述 投票:0回答:5

有没有办法跟踪给定进程的所有文件 I/O?我真正需要的是从给定进程读取/写入的文件的位置(理想情况下,如果它是读取或写入操作,尽管这并不那么重要)。

我可以运行该流程并跟踪它,而不需要附加到现有流程,我认为这要简单得多。是否有任何类型的包装实用程序可以运行一个进程来监视文件访问?

linux file trace
5个回答
55
投票

lsof

尝试作为初学者这样做:

lsof -p <PID>

此命令将列出具有传递的进程 ID 的进程的所有当前打开的文件、fd、套接字。

对于您的特殊需求,请查看我可以提供什么作为监控 php 脚本的解决方案:

php foo.php & _pid=$!
lsof -r1 -p $_pid
kill %1 # if you want to kill php script

strace

我推荐使用

strace
。与
lsof
不同,只要进程正在运行,它就会保持运行。当系统调用被调用时,它会打印出正在调用哪些系统调用。
-e trace=file
仅过滤访问文件系统的系统调用:

sudo strace -f -t -e trace=file php foo.php

或者对于已经运行的进程:

sudo strace -f -t -e trace=file -p <PID>

7
投票

除了 strace 之外,还有另一个选项,它不会显着减慢受监控的进程。使用Liunx内核的fanotify(不要与更流行的inotify混淆)可以监视整个挂载点的IO活动。通过非共享挂载命名空间,给定进程的挂载可以与系统的其余部分隔离(docker 背后的关键技术)。

这个概念的实现可以在我是作者的shournal中找到。

外壳上的示例:

$ shournal -e sh -c 'cat foo > bar'
$ shournal --query --history 1
...
  1 written file(s):
     /home/user/bar
  1 read file(s):
     /home/user/foo 

2
投票

strace 是一个很棒的工具,但它的输出有点冗长。
如果您愿意,可以使用我编写的一个工具,该工具可以处理 strace 输出,并提供包含以下数据的所有访问文件(也包括 TCP 套接字)的 CSV 报告:
1. 文件名
2. 读/写字节
3. 读/写操作次数
4. 文件被打开的次数

它可以在新进程或已经运行的进程上运行(使用/proc/fd数据)。
我发现它对于调试场景和性能分析很有用。
您可以在这里找到它:iotrace

输出示例:

Filename, Read bytes, Written bytes, Opened, Read op, Write op
/dev/pts/1,1,526512,0,1,8904
socket_127.0.0.1:47948->127.0.0.1:22,1781764,396,0,8905,11
myfile.txt,65,0,9,10,0
pipe:[3339],0,0,0,1,0

之后,您可以在Excel或其他工具中处理CSV数据,以进行排序或其他所需的分析。
缺点是您需要下载和编译,而且它并不总是 100% 准确。


1
投票

这样的事情可能会减轻文件活动监控对性能的影响。

$ watch -n 2.0 timeout 0.2 strace -p `pgrep myprogram` -fe trace=file

其中

myprogram
是进程名称,
2.0
是每个监控周期之间的空闲时间,
0.2
是监控周期的长度(以秒为单位)。


0
投票

我是fatrace的忠实粉丝。

示例:

$ sudo fatrace -p $PID
© www.soinside.com 2019 - 2024. All rights reserved.