列出程序访问的文件


64

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

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

目前,我使用:

#!/bin/bash

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

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


鉴于您对的使用strace,我认为您对Linux特别感兴趣。正确?
吉尔斯

Linux是我最关心的问题。
奥莱·丹吉

Answers:


51

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

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


谢谢!strace的输出绝对不可读。我不知道在哪里找到文档-如果它有-h /-help选项,那会很好。我还要感谢一个仅显示文件编辑而不显示访问的选项。
Xerus

@Xerus复制gitlab.com/ole.tange/tangetools并运行make && sudo make install。然后就可以运行了man tracefile
Ole Tange '18

4
不错的工具。它打包,安装:yum -y install https://extras.getpagespeed.com/release-el7-latest.rpmyum -y install tracefile
达尼拉Vershinin

27

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

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

另一种可能更快的方法是预加载一个环绕文件系统访问功能的库:LD_PRELOAD=/path/to/libmywrapper.so mycommand。该LD_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才能使用审核系统。


LD_PRELOAD也不适用于静态二进制文件。
大卫

6

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

lsof -n -p `pidof your_app`

11
但这只是给我一个快照。我需要的是它尝试访问的文件。考虑一下程序由于显示“ Missing file”而拒绝启动的情况。如何确定要查找的文件?
奥莱·丹吉

2

我试过了tracefile。对我来说,比赛比我少strace ... | sed ... | sort -u。我什-s256至添加了strace(1)命令行,但是并没有太大帮助。

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

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

inotifywait -m -r -e OPEN /path/to/traced/directory

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

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

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

EDIT2:至少inotifying文件和从inotifywait命令线(例如符号链接本身时inotifywait -m file symlinkinotifywait symlink file)输出将显示访问哪一个是第一个在命令行(不论哪个,filesymlink被访问)。inotifywait不支持IN_DONT_FOLLOW-当我以编程方式尝试时,它只会使人看到对访问权限的访问file(可能或不会,这正是人们期望的...),而与命令行中的顺序无关


“对我来说,匹配项比我的匹配项少得多”您能分享一个tracefile缺少文件访问权限的示例吗?
Ole Tange

我不确定您要问的是什么:)...如果我尝试查看/ path / to / traced / directory /中的文件,则在inotify输出中看到OPEN ...但是stat(1)似乎是文件在我尝试过的少数情况下没有获得任何结果(我想知道为什么,是某些缓存隐藏了从视图中读取的目录内容)
Tomi Ollila

我在下面评论fanotify帖子(尽管我已经有20多年的历史,但我只有21个声誉;要求发表50条评论一直是我的障碍...)-fanotify是好东西,但不能解决符号链接取消引用的问题(即,在符号链接的情况下,通过读取/ proc / self / fd / <fd> ..可以找到最终访问的文件。总之+1:回答:D
Tomi Ollila

1

虽然它可能无法给您足够的控制权(但是?),但我编写了一个程序,至少使用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    
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.