【问题标题】:Linux - How to track all files accessed by a process?Linux - 如何跟踪进程访问的所有文件?
【发布时间】:2014-12-11 16:49:04
【问题描述】:

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

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

【问题讨论】:

标签: linux file trace


【解决方案1】:

lsof:

尝试这样做作为初学者:

lsof -p <PID>

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

对于您的特殊需求,请参阅我可以提供什么作为监控 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>

【讨论】:

  • 谢谢,这是一个很好的起点!它适用于在运行时已经运行的进程。我正在尝试为整个执行的 PHP 脚本执行此操作,从进程开始跟踪文件直到它存在。查看帮助,有一个 -r 重复选项,但这似乎定期扫描进程打开而不是已打开的文件。本质上我想这样做: lsof -p $$ && exec php foo.php 这似乎没有列出由 foo.php 打开的文件
  • 谢谢,这肯定会提供更多相关信息并显示所有正在加载的 php 扩展,脚本包含 不幸的是,file.txt 没有在输出中列出。我可以通过修改脚本以打印 file.txt 的内容来验证文件是否正在打开,但在 lsof 的输出中我仍然看不到 file.txt。
  • 要正确跟踪 AppImage,我需要以 root 身份运行 strace,但该命令使用我自己的用户。这完成了工作:sudo strace -fte trace=%file -u $(id -un) &lt;COMMAND&gt;
【解决方案2】:

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

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

shell上的例子:

$ 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 

【讨论】:

  • 外部链接作为来源总是受到高度赞赏,但想象一下这个链接将变得无效 - 您的解决方案对于未来的 SO 用户将无法挽救。请考虑在此处发布代码并解释您的解决方案,以便我们都可以学习。
  • @harmonica141:这始终是个问题:写什么,省略什么......一个完整的、最小的例子不会比底部的例子短多少 man7.org/linux/man-pages/man7/fanotify.7.html 。事实上,它可能与领先的unshare( CLONE_NEWNS); 几乎相同。您认为在此处包含完整源代码会有所帮助吗?
【解决方案3】:

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% 准确。

【讨论】:

    【解决方案4】:

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

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

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

    【讨论】:

      猜你喜欢
      • 2020-08-19
      • 1970-01-01
      • 1970-01-01
      • 2011-08-24
      • 2012-01-07
      • 1970-01-01
      • 1970-01-01
      • 2017-06-11
      • 1970-01-01
      相关资源
      最近更新 更多