Из контекста я делаю вывод, что когда вы пишете «индексы», вы на самом деле имеете в виду inodes . В случае, если вы имели в виду индексы, обратите внимание, что каталог , а не состоит из списка файлов в четко определенном порядке, где вы можете сказать: «Мне нужен файл с индексом 3». Каталоги индексируются по именам: вы говорите: «Мне нужен файл с именем foo
». Порядок файлов в каталоге может измениться в любое время.
Предполагая, что вы действительно имеете в виду inodes, нет способа получить доступ к файлу по его inode. Это сделано намеренно: пути к файлам - это то, как применяются разрешения. Доступ к файлу через его индексный дескриптор приведет к обходу всех проверок разрешений в каталоге, который его содержит. Это также было бы возможно только в файловой системе, которая имеет концепцию индексного дескриптора по дизайну, вместо того, чтобы извлекать номера индексного дескриптора из воздуха только потому, что этого требует API. Поэтому, если вам известен только индексный дескриптор файла, поиск его до тех пор, пока не будет найдено имя, - единственный способ работать с этим файлом.
Даже если бы существовал способ найти файл по inode, это не решило бы вашу проблему, а просто немного переместило бы его. Это сделает его прозрачным, когда файл будет переименован после того, как find
нашел его, но до того, как он что-то с ним сделает. Однако, если файл был удален и был создан другой файл с тем же индексом, find
обратится не к тому файлу.
Файловый API не позволяет сделать атомарный снимок дерева каталогов. Есть несколько решений вашей проблемы; какой из них может работать для вас, зависит от вашего сценария использования.
Существуют и другие способы регистрации всех команд, выполненных пользователем. С установленным sysdig
можно запустить что-то вроде
# sysdig "user.name = jdoe and evt.type = execve"
для регистрации всех execve(2)
вызовов по jdoe
; опция -p
для sysdig
позволяет настроить формат вывода и т. д.
Другим способом было бы использование SystemTap
, преимущество которого заключается в том, что он поддерживается RedHat; здесь мы предполагаем, что jdoe
имеет UID 1000
;
probe begin {
printf("begin trace...\n\n")
}
probe syscall.execve.return {
if (uid() != 1000) next;
printf("runs %s[%d]: %s\n", execname(), pid(), cmdline_str());
}
затем это можно запустить с помощью чего-то вроде
# stap-prep
...
# stap whatyousavedtheaboveas.stp
Оба метода, скорее всего, потребуют корректировок, чтобы получить именно то, что вам нужно, обработать условия ошибок, когда execve
не работает, и т. д. С другой стороны, sysdig
и SystemTap
намного эффективнее, чемstrace
(run vmstat 1
и посмотрите, как strace
выталкивает контекстные переключатели через крышу во время работы ).
В руководстве для strace
упоминается, что:
ОШИБКИ
Программы, использующие бит setuid, не имеют действующих привилегий идентификатора пользователя во время трассировки.
Хотя я подозреваю, что это больше связано с безопасностью отладки процесса setuid, чем с ошибкой.Если не ошибаюсь, strace
использует тот же интерфейс трассировки, что и, скажем, gdb
, и позволяет среди прочего модифицировать память запущенного процесса. Возможность сделать это с процессом, который работает с большими привилегиями, чем вы должны иметь, была бы
плохая идея.