プログラムがアクセスしたファイルをリストする


64

time 特定のコマンドにかかるCPU時間を把握したい場合は、すばらしいコマンドです。

プログラムとその子によってアクセスされているファイルをリストできる類似のものを探しています。リアルタイムで、またはその後のレポートとして。

現在使用しているもの:

#!/bin/bash

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

ただし、実行するコマンドにが含まれる場合は失敗しますsudo。あまりインテリジェントではありません(既存のファイルまたは権限の問題があるファイルのみを一覧表示するか、読み取りファイルと書き込みファイルにグループ化できると便利です)。またstrace遅いので、より速い選択で良いでしょう。


の使用を考えるとstrace、Linuxに特に興味があると思います。正しい?
ジル 'SO-悪であるのをやめる'

Linuxは私の最大の関心事です。
オレ丹下

回答:


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クローンgitlab.com/ole.tange/tangetoolsと実行make && sudo make install。その後、実行できますman tracefile
オレ丹下

4
素敵なツール。パッケージ化して、インストールする:yum -y install https://extras.getpagespeed.com/release-el7-latest.rpmおよびyum -y install tracefile
Danila Vershinin

27

システムコールはを使用してトレースできますがstrace、実際には速度のペナルティが避けられません。straceコマンドが昇格された特権で実行される場合は、rootとして実行する必要があります。

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

より高速になる可能性が高い別の方法は、ファイルシステムアクセス関数をラップするライブラリをプリロードすることですLD_PRELOAD=/path/to/libmywrapper.so mycommandLD_PRELOAD環境変数は、システム特権で起動されたプログラムに渡されることはありません。そのラッパーライブラリのコードを記述する必要があります(「楽しさと利益のためにライブラリインターポーザを構築する」の例です)。再利用可能なコードがWebで利用できるかどうかはわかりません。

特定のディレクトリ階層内のファイルを監視している場合、そのビューを介したすべてのアクセスがログに記録されるように、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できます。使用可能なフィルターについては、manページをご覧ください。監査システムを使用するには、rootになる必要があります。


LD_PRELOADまた、静的バイナリでは動作しません。
デビッド考えると

6

lsof(おそらくプログラムとその子のgrepにパイプされる)が欲しいと思う。ファイルシステム上で現在アクセスされているすべてのファイルが表示されます。プロセスによってアクセスされるファイルに関する情報については、こちらから

lsof -n -p `pidof your_app`

11
しかし、それは私にスナップショットを提供するだけです。必要なのは、アクセスしようとしたファイルです。「ファイルがありません」と表示されているため、プログラムが起動を拒否する状況を考えてください。どのファイルを探していたかを知るにはどうすればよいですか?
オレ丹下

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:少なくともファイルとinotifywaitコマンドライン(例えばからシンボリックリンクそのものをinotifyingときinotifywait -m file symlinkまたはinotifywait symlink file1が(これは、関係なく、コマンドラインで最初にされているアクセスが表示されます)出力filesymlinkアクセスされます)。inotifywaitはIN_DONT_FOLLOWをサポートしていません-プログラムで試行したときにfile、コマンドラインの順序に関係なく、アクセスを確認するだけです(期待どおりの場合もそうでない場合もあります)。


「私にとっては、自分よりもはるかに少ない一致しか得られませんでした」tracefileファイルアクセスの欠落の例を共有できますか?
オレ丹下

あなたが正確に何を求めているのかわかりません:)... / path / to / traced / directory /内のファイルを検索しようとすると、inotifyの出力にOPENが表示されます...しかし、stat(1)のファイルは私が試したいくつかのケースで結果が得られない(なぜ、キャッシュがビューからディレクトリコンテンツの読み取りを隠しているのだろうか)
Tomi Ollila

以下のfanotifyの投稿にコメントしています(10年以上アカウントを持っていますが、評判が21しかありません;コメントに50を要求することは常に私にとって障害です...)-fanotifyは良いものですが、できませんシンボリックリンクの参照解除の問題を回避します(つまり、シンボリックリンクの場合、アクセスした最終ファイルは/ proc / self / fd / <fd>を読み取ることで見つかります。..とにかく+1:ingの答え:D
トミオリラ

1

まだ十分な制御が得られないかもしれませんが(まだ?)、少なくとも部分的にニーズを満たすプログラムを作成しました。linux-kernelの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    
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.