Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

time is a brilliant command if you want to figure out how much CPU time a given command takes.

I am looking for something similar that can list the files being accessed by a program and its children. Either in real time or as a report afterwards.

Currently I use:

#!/bin/bash

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

but its fails if the command to run involves sudo. It is not very intelligent (it would be nice if it could only list files existing or that had permission problems or group them into files that are read and files that are written). Also strace is slow, so it would be good with a faster choice.

share|improve this question
    
Given your use of strace, I assume you're specifically interested in Linux. Correct? –  Gilles Aug 16 '11 at 23:02
    
Linux is my primary concern. –  Ole Tange Aug 22 '11 at 12:20

3 Answers 3

up vote 13 down vote accepted

I gave up and coded my own tool. It allows for:

-a all files
-e existing files
-n non-existing files

It only outputs the files so you do not need to deal with the output from strace.

https://github.com/ole-tange/tangetools/tree/master/tracefile

share|improve this answer

You can trace the system calls with strace, but there is indeed an inevitable speed penalty. You need to run strace as root if the command runs with elevated privileges:

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

Another method that's likely to be faster is to preload a library that wraps around filesystem access functions: LD_PRELOAD=/path/to/libmywrapper.so mycommand. The LD_PRELOAD environment variable won't be passed to programs invoked with elevated privileges. You'd have to write the code of that wrapper library (here's an example from “Building library interposers for fun and profit”); I don't know if there is reusable code available on the web.

If you're monitoring the files in a particular directory hierarchy, you can make a view of the filesystem with LoggedFS such that all accesses through that view are logged.

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

To configure LoggedFS, start with the sample configuration shipped with the program and read LoggedFS configuration file syntax.

Another possibility is Linux's audit subsystem. Make sure the auditd daemon is started, then configure what you want to log with auditctl. Each logged operation is recorded in /var/log/audit/audit.log (on typical distributions). To start watching a particular file:

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

If you put a watch on a directory, the files in it and its subdirectories recursively are also watched. Take care not to watch the directory containing the audit logs. You can restrict the logging to certain processes, see the auditctl man page for the available filters. You need to be root to use the audit system.

share|improve this answer

I think you want lsof (possibly piped to a grep on the program and it's children). It will tell you every file that's currently being accessed on the filesystem.

share|improve this answer
3  
But it only gives me a snapshot. What I need is what files it tried to access. Think of the situation where a program refuses to start because it says "Missing file". How do I figure out what file it was looking for? –  Ole Tange Aug 22 '11 at 12:21

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.