列出程序访问的文件

列出程序访问的文件

time如果您想计算给定命令占用了多少 CPU 时间,这是一个出色的命令。

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

目前我使用:

#!/bin/bash

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

但如果要运行的命令涉及sudo.它不是很智能(如果它只能列出现有的文件或有权限问题的文件或将它们分组为读取的文件和写入的文件,那就太好了)。而且strace速度很慢,所以如果有更快的选择就好了。

答案1

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

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://codeberg.org/tange/tangetools/src/branch/master/tracefile

答案2

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

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

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

如果您正在监视特定目录层次结构中的文件,则可以使用以下命令创建文件系统的视图记录文件系统这样,通过该视图的所有访问都会被记录。

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 才能使用审核系统。

答案3

我认为你想要 lsof (可能通过管道传输到程序及其子项上的 grep)。它会告诉您文件系统上当前正在访问的每个文件。有关进程访问哪些文件的信息(从这里):

lsof -n -p `pidof your_app`

答案4

虽然它可能还没有给你足够的控制权(还?),但我已经编写了一个程序,它至少部分满足了你的需求,使用 linux 内核的 fanotify 和 unshare 来仅监视由特定进程及其子进程修改(或读取)的文件。与strace相比,它相当快(;

可以在以下位置找到: https://github.com/tycho-kirchner/shournal

外壳上的示例:

$ 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    

相关内容