Listet die Dateien auf, auf die ein Programm zugreift

64

time ist ein brillanter Befehl, wenn Sie herausfinden möchten, wie viel CPU-Zeit ein bestimmter Befehl benötigt.

Ich suche nach etwas Ähnlichem, das die Dateien auflisten kann, auf die von einem Programm und seinen Kindern zugegriffen wird. Entweder in Echtzeit oder als Bericht danach.

Zur Zeit benutze ich:

#!/bin/bash

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

Es schlägt jedoch fehl, wenn der auszuführende Befehl einschließt sudo. Es ist nicht sehr intelligent (es wäre schön, wenn es nur Dateien auflisten könnte, die existieren oder Berechtigungsprobleme hatten, oder sie in gelesene und geschriebene Dateien gruppieren könnte). Ist auch stracelangsam, also wäre es gut mit einer schnelleren Wahl.

Ole Tange
quelle
Aufgrund Ihrer Verwendung von stracegehe ich davon aus, dass Sie speziell an Linux interessiert sind. Richtig?
Gilles 'SO - hör auf böse zu sein'
Linux ist mein Hauptanliegen.
Ole Tange

Antworten:

51

Ich habe aufgegeben und mein eigenes Werkzeug programmiert. Um aus seinen Dokumenten zu zitieren:

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

Es werden nur die Dateien ausgegeben, sodass Sie sich nicht mit der Ausgabe von befassen müssen strace.

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

Ole Tange
quelle
Vielen Dank! Die Ausgabe von strace ist absolut unlesbar. Ich weiß allerdings nicht, wo ich die Dokumente finden soll - es wäre schön, wenn es eine -h / - help-Option gäbe. Ich würde auch eine Option begrüßen, die nur Dateibearbeitungen und keine Zugriffe anzeigt.
Xerus
@Xerus Clone gitlab.com/ole.tange/tangetools und startemake && sudo make install . Dann kannst du rennen man tracefile.
Ole Tange
4
Nettes Werkzeug. Verpackt, zu installieren: yum -y install https://extras.getpagespeed.com/release-el7-latest.rpmundyum -y install tracefile
Danila Vershinin
27

Sie können die Systemaufrufe mit verfolgen strace, aber es gibt in der Tat eine unvermeidliche Geschwindigkeitsstrafe. Sie müssen straceals root ausgeführt werden, wenn der Befehl mit erhöhten Rechten ausgeführt wird:

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

Eine andere Methode , die schneller sein dürfte ist , ist eine Bibliothek vorab zu laden, die sich um Dateisystem - Zugriffsfunktionen wickelt: LD_PRELOAD=/path/to/libmywrapper.so mycommand. Die LD_PRELOADUmgebungsvariable wird nicht an Programme übergeben, die mit erhöhten Rechten aufgerufen werden. Sie müssten den Code dieser Wrapperbibliothek schreiben ( hier ein Beispiel aus „Erstellen von Interposern für die Bibliothek aus Spaß und Gewinn“ ). Ich weiß nicht, ob im Web wiederverwendbarer Code verfügbar ist.

Wenn Sie die Dateien in einer bestimmten Verzeichnishierarchie überwachen, können Sie mit LoggedFS eine Ansicht des Dateisystems erstellen , sodass alle Zugriffe über diese Ansicht protokolliert werden.

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

Um LoggedFS zu konfigurieren, beginnen Sie mit der mit dem Programm gelieferten Beispielkonfiguration und lesen Sie die Syntax der LoggedFS-Konfigurationsdatei .

Eine andere Möglichkeit ist das Audit-Subsystem von Linux . Stellen Sie sicher, dass der auditdDämon gestartet ist, und konfigurieren Sie dann, mit was Sie sich anmelden möchten auditctl. Jeder protokollierte Vorgang wird in /var/log/audit/audit.log(bei typischen Distributionen) aufgezeichnet . So starten Sie das Ansehen einer bestimmten Datei:

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

Wenn Sie ein Verzeichnis überwachen, werden auch die darin enthaltenen Dateien und deren Unterverzeichnisse rekursiv überwacht. Achten Sie darauf, das Verzeichnis mit den Überwachungsprotokollen nicht zu überwachen. Sie können die Protokollierung auf bestimmte Prozesse beschränken. Informationen zu auditctlden verfügbaren Filtern finden Sie auf der Manpage. Sie müssen als Root angemeldet sein, um das Audit-System verwenden zu können.

Gilles 'SO - hör auf böse zu sein'
quelle
LD_PRELOADfunktioniert auch nicht auf statischen Binärdateien.
David Given
6

Ich denke, Sie wollen lsof (möglicherweise zu einem Grep auf dem Programm und es ist Kinder). Es wird Ihnen jede Datei anzeigen, auf die aktuell im Dateisystem zugegriffen wird. Informationen darüber, auf welche Dateien der Prozess zugreift ( von hier aus ):

lsof -n -p `pidof your_app`
Onkeljamil
quelle
11
Aber es gibt mir nur einen Schnappschuss. Was ich brauche, ist, auf welche Dateien es zugreifen wollte. Denken Sie an die Situation, in der ein Programm aufgrund der Meldung "Fehlende Datei" nicht gestartet werden kann. Wie finde ich heraus, nach welcher Datei gesucht wurde?
Ole Tange
2

Ich habe es versucht tracefile. Für mich gab es viel weniger Übereinstimmungen als meine eigenen strace ... | sed ... | sort -u. Ich habe sogar -s256die strace(1)Befehlszeile hinzugefügt , aber es hat nicht viel geholfen ...

Dann habe ich das versucht loggedfs. Zuerst schlug es fehl, da ich keinen Lese- / Schreibzugriff auf das Verzeichnis hatte, mit dem ich mich anmelden wollte. Nachdem ich vorübergehend chmod 755 gemacht habe, habe ich ein paar Hits bekommen ...

Für mich scheint es jedoch am besten zu sein, Folgendes zu tun:

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

Anschließend wird die Ausgabe nach dem Ausführen des gewünschten Prozesses nachbearbeitet.

Dies erfasst weder den Dateizugriffsprozess außerhalb des verfolgten Verzeichnisses, noch weiß dies, ob ein anderer Prozess auf denselben Verzeichnisbaum zugegriffen hat, aber in vielen Fällen ist dies ein ausreichend gutes Tool, um die Aufgabe zu erledigen.

BEARBEITEN: inotifywait fängt keinen Symlink-Zugriff ab (nur die Ziele, nachdem die Symlinks aufgelöst wurden). Das traf mich, als ich Bibliotheken archivierte, auf die ein Programm für die zukünftige Verwendung zugreift. Verwenden Sie eine zusätzliche Perl-Glob-Hackerei, um die Symlinks in den gemeldeten Bibliotheken auszuwählen, um die Arbeit in diesem speziellen Fall zu erledigen.

EDIT2: Zumindest wenn sich Dateien und Symlinks über die Befehlszeilenausgabe inotifywait (z. B. inotifywait -m file symlinkoder inotifywait symlink file) inotifizieren, wird der Zugriff darauf angezeigt , welche zuerst in der Befehlszeile angezeigt wird (unabhängig davon, auf welche filevon symlinkzugegriffen wird). inotifywait unterstützt IN_DONT_FOLLOW nicht - was, als ich es programmatisch versuchte, einem den Zugriff auf file(was möglicherweise erwartet wird, oder auch nicht ...) unabhängig von der Reihenfolge in der Befehlszeile anzeigt

Tomi Ollila
quelle
"Für mich gab es viel weniger Übereinstimmungen als meine eigenen." Können Sie ein Beispiel für das tracefileFehlen eines Dateizugriffs teilen ?
Ole Tange
Ich bin mir nicht sicher, was Sie genau fragen:) ... Wenn ich versuche, Dateien in / path / to / traced / directory / zu suchen, wird OPEN in der Ausgabe von inotify angezeigt ... ABER stat (1) die Dateien, die mir scheinen in den wenigen Fällen, in denen ich es versuchte, keine Ergebnisse zu erzielen (ich frage mich, warum in einigen Fällen das Cachen das Auslesen von Verzeichnisinhalten verhindert)
Tomi Ollila
Ich kommentiere den Fanotify-Beitrag unten (ich habe nur 21 Ruf, obwohl ich seit mehr als einem Jahrzehnt verantwortlich bin; 50 für das Kommentieren zu verlangen, war für mich immer ein Hindernis ...) - Fanotify ist gutes Zeug, kann es aber nicht gehen um die Symlink dereferenzieren Ausgabe (dh bei Symlinks, zugegriffen die letzte Datei durch das Lesen / proc / self / fd / <fd> .. sowieso +1 gefunden: ing die Antwort: D
Tomi Ollila
1

Auch wenn es Ihnen (noch?) Nicht genug Kontrolle gibt, habe ich ein Programm geschrieben, das Ihre Anforderungen zumindest teilweise erfüllt. Dabei wird das Fanotify und Unshare des Linux-Kernels verwendet, um nur Dateien zu überwachen, die von einem bestimmten Prozess und seinen untergeordneten Elementen geändert (oder gelesen) wurden . Im Vergleich zu strace ist es ziemlich schnell (;

Es kann auf https://github.com/tycho-kirchner/shournal gefunden werden

Beispiel auf der 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    
laichen
quelle