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

64

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

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

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

#!/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
@Xerus Clone 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
Данила Вершинин
27

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

Жиль "ТАК - перестань быть злым"
источник
LD_PRELOADтакже не будет работать на статических двоичных файлах.
Дэвид Дан
6

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

lsof -n -p `pidof your_app`
unclejamil
источник
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: по крайней мере, когда inotifying файлы и сами символические ссылки из вывода командной строки inotifywait (например, inotifywait -m file symlinkor inotifywait symlink file) покажет доступ к тому, кто находится первым в командной строке (независимо от того, к какому fileиз symlinkних обращаются). inotifywait не поддерживает IN_DONT_FOLLOW - который, когда я пытался программно, просто позволяет увидеть доступ file(который может или не может быть тем, что вы ожидаете ...) независимо от порядка в командной строке

Томи Оллила
источник
«Для меня это дало гораздо меньше совпадений, чем у меня». Можете ли вы поделиться примером tracefileотсутствия доступа к файлу?
Оле Танге
Я не уверен, что именно вы спрашиваете:) ... Если я пытаюсь посмотреть файлы в / path / to / traced / directory /, я вижу OPEN в выводе inotify ... НО stat (1) в файлах, которые мне кажутся не получить результатов в тех немногих случаях, которые я пытался (интересно, почему некоторые кэширующие скрывают чтение содержимого каталога из поля зрения)
Томи Оллила
Я комментирую пост fanotify ниже (у меня только 21 репутация, хотя у меня был аккаунт более десяти лет; требовать 50 для комментирования всегда было препятствием для меня ...) - fanotify - хороший материал, но не может обойти проблему разыменования символьных ссылок (т. е. в случае символических ссылок окончательный доступ к файлу можно найти, прочитав / proc / self / fd / <fd> .. в любом случае +1: в ответ: D
Томи Оллила
1

Хотя это может не дать вам достаточного контроля (пока?), Я написал программу, которая хотя бы частично удовлетворяет ваши потребности, используя 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    
порождать
источник