it-swarm-ru.tech

Список файлов, к которым обращается программа

time - блестящая команда, если вы хотите выяснить, сколько процессорного времени занимает данная команда.

Я ищу что-то подобное, что может перечислить файлы, к которым обращается программа и ее дочерние элементы. Либо в режиме реального времени, либо в виде отчета.

В настоящее время я использую:

#!/bin/bash

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

но он завершается неудачно, если для запуска команды используется Sudo. Он не очень интеллектуален (было бы хорошо, если бы он мог только перечислять файлы, существующие или у которых были проблемы с правами доступа, или группировать их в файлы, которые читаются, и файлы, которые записываются). Кроме того, strace работает медленно, поэтому было бы неплохо с более быстрым выбором.

65
Ole Tange

Я сдался и закодировал свой собственный инструмент. Чтобы процитировать его документы:

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

56
Ole Tange

Вы можете отследить системные вызовы с помощью 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, чтобы использовать систему аудита.

28
Gilles 'SO- stop being evil'

Я думаю, что вы хотите lsof (возможно, по каналу программы, и это дети). Он сообщит вам каждый файл, к которому в данный момент обращаются в файловой системе. Для получения информации о том, какие файлы доступны процессу ( отсюда ):

lsof -n -p `pidof your_app`
7
unclejamil

Я попробовал это tracefile. Для меня это дало гораздо меньше совпадений, чем мой собственный strace ... | sed ... | sort -u. Я даже добавил -s256 в командную строку strace(1), но это не сильно помогло ...

Тогда я попробовал это loggedfs. Сначала это не удалось, так как у меня не было доступа для чтения/записи к каталогу, в который я пытался войти. После выполнения chmod 755 временно я получил несколько хитов ...

Но, мне кажется, лучше всего сделать следующее:

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

А затем постобработать вывод после запуска интересующего процесса.

Это не перехватывает доступ к процессу обработки файлов из отслеживаемый каталог, и при этом он не знает, получил ли какой-либо другой процесс доступ к тому же дереву каталогов, но во многих случаях это достаточно хороший инструмент для получения задания. сделанный.

Правка: inotifywait не перехватывает доступ к символическим ссылкам (только цели после разрешения символических ссылок). Это меня поразило, когда я заархивировал библиотеки, к которым обращалась программа для будущего использования. Использовал некоторые дополнительные Perl glob hackery, чтобы выбрать символические ссылки вдоль уведомленных библиотек, чтобы выполнить работу в этом конкретном случае.

EDIT2: по крайней мере, когда inotifying файлы и сами символические ссылки из командной строки inotifywait (например, inotifywait -m file symlink или inotifywait symlink file) выводит доступ к первому в командной строке (независимо от того, что file из symlink равно Достигано). inotifywait не поддерживает IN_DONT_FOLLOW - который, когда я пытался программно, просто позволяет увидеть доступ к file (который может или не может быть тем, что ожидается ...) независимо от порядка в командной строке

2
Tomi Ollila

Хотя это может не дать вам достаточного контроля (пока?), Я написал программу, которая хотя бы частично удовлетворяет ваши потребности, используя fanotify и unshare ядра Linux для мониторинга только файлов, измененных (или прочитанных) определенным процессом и его дочерними элементами. , По сравнению с 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    
1
spawn