it-swarm.cn

列出程序访问的文件

如果您想弄清楚给定命令需要多少CPU时间,则time是一个出色的命令。

我正在寻找类似的东西,可以列出程序及其子级正在访问的文件。实时或事后报告。

目前,我使用:

#!/bin/bash

strace -ff -e trace=file "[email protected]" 2>&1 | Perl -ne 's/^[^"]+"(([^\\"]|\\[\\"nt])*)".*/$1/ && print'

但如果运行的命令涉及Sudo,则失败。它不是很聪明(如果它只能列出现有文件或存在权限问题的文件,或者将它们分为读取的文件和写入的文件,那将是很好的选择)。 strace也很慢,因此选择较快的方法会很好。

65
Ole Tange

我放弃并编写了自己的工具。引用其文档:

SYNOPSIS
    tracefile [-adefnu] command
    tracefile [-adefnu] -p pid

OPTIONS
    -a        List all files
    -d        List only dirs
    -e        List only existing files
    -f        List only files
    -n        List only non-existing files
    -p pid    Trace process id
    -u        List only files once

它仅输出文件,因此您不需要处理strace的输出。

https://gitlab.com/ole.tange/tangetools/tree/master/tracefile

56
Ole Tange

您可以使用strace跟踪系统调用,但是确实存在不可避免的速度损失。如果命令以提升的特权运行,则需要以root用户身份运行strace

Sudo strace -f -o foo.trace su user -c 'mycommand'

另一种可能更快的方法是预加载一个环绕文件系统访问功能的库:LD_PRELOAD=/path/to/libmywrapper.so mycommandLD_PRELOAD环境变量不会传递给以提升的特权调用的程序。您必须编写该包装器库的代码( 这里是“为娱乐和利润而构建库中介程序” )的示例;我不知道网络上是否有可重用的代码。

如果要监视特定目录层次结构中的文件,则可以使用 LoggedFS 来查看文件系统,以便记录通过该视图进行的所有访问。

loggedfs -c my-loggedfs.xml /logged-view
mycommand /logged-view/somedir

要配置LoggedFS,请从程序附带的示例配置开始,然后阅读 LoggedFS配置文件语法

另一种可能性是Linux的 审计子系统 。确保auditd守护程序已启动,然后使用 auditctl 配置要记录的内容。每个记录的操作都记录在/var/log/audit/audit.log(在典型分布上)。要开始观看特定文件:

auditctl -a exit,always -w /path/to/file

如果将监视放在目录中,则将以递归方式监视其中的文件及其子目录。注意不要观看包含审核日志的目录。您可以将日志记录限制为某些进程,有关可用过滤器的信息,请参见auditctl手册页。您需要具有root才能使用审核系统。

28

我认为您想要lsof(可能通过管道传输到该程序的grep上,并且是孩子的)。它会告诉您文件系统上当前正在访问的每个文件。有关进程访问哪些文件的信息( 从此处 ):

lsof -n -p `pidof your_app`
7
unclejamil

我尝试了tracefile。对我来说,与我自己的_strace ... | sed ... | sort -u_相比,匹配次数少得多。我什至在strace(1)命令行中添加了_-s256_,但并没有太大帮助...

然后我尝试了loggedfs。首先,它失败了,因为我没有对尝试使用它登录的目录的读写权限。暂时做完chmod 755之后,我确实得到了一些点击...

但是,对我来说,执行以下操作似乎效果最好:

_inotifywait -m -r -e OPEN /path/to/traced/directory_

然后在运行感兴趣的过程后对输出进行后处理。

这不会捕获跟踪目录的文件进程访问异常,也不知道其他进程是否访问了同一目录树,但是在许多情况下,这是完成任务的足够好工具完成。

编辑:inotifywait不会捕获符号链接访问(只是符号链接解析后的目标)。当我归档某个程序访问的库以供将来使用时,受到了这一打击。使用了一些额外的Perl glob骇客来选择通知库中的符号链接,以完成该特定情况下的工作。

EDIT2:至少在从inotifywait命令行初始化文件并自身进行符号链接时(例如_inotifywait -m file symlink_或_inotifywait symlink file_),输出将显示对命令行中第一个的访问权限(无论哪个_filesymlink已访问)。 inotifywait不支持IN_DONT_FOLLOW-当我以编程方式尝试时,它只会使人看到对file的访问权限(可能或可能不会是人们期望的...),无论命令行中的顺序如何

2
Tomi Ollila

尽管它可能无法给您足够的控制权(但是?),但我编写了一个程序,至少使用Linux内核的fanotify和unshare来部分满足您的需求,该程序仅监视由特定进程及其子进程修改(或读取)的文件。 。与strace相比,它相当快(;

可以在 https://github.com/tycho-kirchner/shournal 上找到

Shell上的示例:

$ shournal -e sh -c 'echo hi > foo1; echo hi2 > foo2'
$ shournal -q --history 1
  # ...
  Written file(s):                                                                                                                                                                              
 /tmp/foo1 (3 bytes) Hash: 15349503233279147316                                                                                                                                             
 /tmp/foo2 (4 bytes) Hash: 2770363686119514911    
1
spawn