Elenca i file a cui accede un programma


64

time è un comando brillante se vuoi capire quanto tempo CPU impiega un dato comando.

Sto cercando qualcosa di simile che possa elencare i file a cui accede un programma e i suoi figli. O in tempo reale o come rapporto successivo.

Attualmente uso:

#!/bin/bash

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

ma fallisce se il comando da eseguire comporta sudo. Non è molto intelligente (sarebbe bello se potesse elencare solo i file esistenti o che presentavano problemi di autorizzazione o raggrupparli in file letti e file scritti). Inoltre straceè lento, quindi sarebbe una scelta più veloce.


Dato il tuo uso di strace, presumo che tu sia particolarmente interessato a Linux. Corretta?
Gilles 'SO- smetti di essere malvagio' il

Linux è la mia principale preoccupazione.
Ole Tange,

Risposte:


51

Ho rinunciato e codificato il mio strumento. Per citare dai suoi documenti:

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

Emette solo i file, quindi non è necessario gestire l'output da strace.

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


Grazie! L'output di strace è assolutamente illeggibile. Non so dove trovare i documenti, sarebbe bello se avesse un'opzione di aiuto -h / -. Gradirei anche un'opzione che mostra solo le modifiche ai file, non gli accessi.
Xerus,

@Xerus Clone gitlab.com/ole.tange/tangetools ed esegui make && sudo make install. Quindi puoi correre man tracefile.
Ole Tange,

4
Strumento carino. Impacchettato, per installare: yum -y install https://extras.getpagespeed.com/release-el7-latest.rpmeyum -y install tracefile
Danila Vershinin il

27

Puoi rintracciare le chiamate di sistema con strace, ma c'è davvero un'inevitabile penalità di velocità. È necessario eseguire stracecome root se il comando viene eseguito con privilegi elevati:

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

Un altro metodo che è probabile che sia più veloce è quello di precaricare una libreria che avvolge le funzioni di accesso filesystem: LD_PRELOAD=/path/to/libmywrapper.so mycommand. La LD_PRELOADvariabile di ambiente non verrà passata ai programmi richiamati con privilegi elevati. Dovresti scrivere il codice di quella libreria wrapper ( ecco un esempio di "Costruire interposer di librerie per divertimento e profitto" ); Non so se ci sono codici riutilizzabili disponibili sul web.

Se stai monitorando i file in una particolare gerarchia di directory, puoi creare una vista del filesystem con LoggedFS in modo tale che tutti gli accessi attraverso quella vista siano registrati.

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

Per configurare LoggedFS, iniziare con la configurazione di esempio fornita con il programma e leggere la sintassi del file di configurazione di LoggedFS .

Un'altra possibilità è il sottosistema di controllo di Linux . Assicurati che il auditddemone sia avviato, quindi configura ciò con cui vuoi accedere auditctl. Ogni operazione registrata viene registrata in /var/log/audit/audit.log(su distribuzioni tipiche). Per iniziare a guardare un determinato file:

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

Se si inserisce un watch in una directory, vengono guardati anche i file in essa contenuti e le sue sottodirectory ricorsivamente. Fare attenzione a non guardare la directory contenente i registri di controllo. È possibile limitare la registrazione a determinati processi, consultare la auditctlpagina man per i filtri disponibili. Devi essere root per usare il sistema di controllo.


LD_PRELOADinoltre non funzionerà su binari statici.
David Dato

6

Penso che tu voglia lsof (possibilmente convogliato ad un grep sul programma ed è bambini). Ti dirà ogni file a cui si accede attualmente sul filesystem. Per informazioni su quali file sono accessibili per processo ( da qui ):

lsof -n -p `pidof your_app`

11
Ma mi dà solo un'istantanea. Ciò di cui ho bisogno è quali file ha tentato di accedere. Pensa alla situazione in cui un programma si rifiuta di avviarsi perché dice "File mancante". Come faccio a capire quale file stava cercando?
Ole Tange,

2

Ci ho provato tracefile. Per me ha dato molte meno partite della mia strace ... | sed ... | sort -u. Ho anche aggiunto -s256alla strace(1)riga di comando, ma non ha aiutato molto ...

Poi l'ho provato loggedfs. Innanzitutto non è riuscito poiché non avevo accesso in lettura / scrittura alla directory in cui ho provato ad accedere. Dopo aver fatto temporaneamente Chmod 755 ho avuto dei successi ...

Ma, per me, fare quanto segue sembra funzionare meglio:

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

E quindi postelaborare l'output dopo aver eseguito il processo di interesse.

Questo non rileva l'accesso al processo dei file all'esterno della directory tracciata né questo non sa se qualche altro processo abbia avuto accesso allo stesso albero di directory, ma in molti casi questo è uno strumento abbastanza buono per portare a termine il lavoro.

EDIT: inotifywait non rileva l'accesso al collegamento simbolico (solo gli obiettivi dopo che i collegamenti simbolici sono stati risolti). Sono stato colpito da questo quando ho archiviato le librerie a cui accedeva un programma per uso futuro. Ho usato un po 'di hacker perl glob in più per scegliere i collegamenti simbolici lungo le librerie notificate per fare il lavoro in quel caso particolare.

EDIT2: almeno quando si inotificano file e collegamenti simbolici dall'output della riga di comando di inotifywait (ad es. inotifywait -m file symlinkO inotifywait symlink file) si mostrerà l'accesso a quale si trova per primo nella riga di comando (indipendentemente da quale filedi symlinksi accede). inotifywait non supporta IN_DONT_FOLLOW - che, quando ho provato a livello di programmazione, consente solo di vedere l'accesso file(che può o meno essere quello che ci si aspetta ...) indipendentemente dall'ordine nella riga di comando


"Per me ha dato molte meno corrispondenze delle mie" Puoi condividere un esempio di tracefilemancato accesso a un file?
Ole Tange,

Non sono sicuro di cosa ti chiederai esattamente:) ... Se provo a cercare i file all'interno di / path / to / tracing / directory / vedo APERTO in inotify output ... MA stat (1) ing i file mi sembrano per non ottenere risultati nei pochi casi che ho provato (mi chiedo perché, un po 'di cache nasconde il contenuto della directory leggendo dalla vista)
Tomi Ollila

Sto commentando il post di fanotify di seguito (ho solo 21 reputazione, anche se ho avuto conto per più di un decennio; richiederne 50 per commentare è sempre stato un ostacolo per me ...) - fanotify è roba buona, ma non posso aggirare il problema di dereference symlink (cioè in caso di symlink, il file finale accessibile si trova leggendo / proc / self / fd / <fd> .. comunque +1: ing la risposta: D
Tomi Ollila

1

Anche se potrebbe non darti abbastanza controllo (ancora?) Ho scritto un programma, che soddisfa almeno parzialmente le tue esigenze, usando fanotify e unshare del kernel linux per monitorare solo i file modificati (o letti) da un processo specifico e dai suoi figli . Rispetto allo strace, è abbastanza veloce (;

Può essere trovato su https://github.com/tycho-kirchner/shournal

Esempio sulla 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    
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.