Я столкнулся с этой проблемой, и ни один из этих ответов не дает ответа на вопрос "сколько часов каждый процесс использует в настоящее время?" Все строки указывают на то, сколько экземпляров открыто, что является лишь частью истории, а трассировка полезна только для того, чтобы увидеть, как открываются новые часы.
TL; DR: Это даст вам файл со списком открытых inotify
экземпляров и количеством часов, которые они имеют, а также pids и двоичные файлы, которые их породили, отсортированные в порядке убывания по количеству часов:
sudo lsof | awk '/anon_inode/ { gsub(/[urw]$/,"",$4); print "/proc/"$2"/fdinfo/"$4; }' | while read fdi; do count=$(sudo grep -c inotify $fdi); exe=$(sudo readlink $(dirname $(dirname $fdi))/exe); echo -e $count"\t"$fdi"\t"$exe; done | sort -nr > watches
Это большой беспорядок, вот как я туда попал. Для начала я запустил tail
тестовый файл и посмотрел на открытые файлы:
joel@gladstone:~$ tail -f test > /dev/null &
[3] 22734
joel@opx1:~$ ls -ahltr /proc/22734/fd
total 0
dr-xr-xr-x 9 joel joel 0 Feb 22 22:34 ..
dr-x------ 2 joel joel 0 Feb 22 22:34 .
lr-x------ 1 joel joel 64 Feb 22 22:35 4 -> anon_inode:inotify
lr-x------ 1 joel joel 64 Feb 22 22:35 3 -> /home/joel/test
lrwx------ 1 joel joel 64 Feb 22 22:35 2 -> /dev/pts/2
l-wx------ 1 joel joel 64 Feb 22 22:35 1 -> /dev/null
lrwx------ 1 joel joel 64 Feb 22 22:35 0 -> /dev/pts/2
Итак, 4 - это то, что мы хотим исследовать. Давайте посмотрим, что fdinfo
для этого:
joel@opx1:~$ cat /proc/22734/fdinfo/4
pos: 0
flags: 00
mnt_id: 11
inotify wd:1 ino:15f51d sdev:ca00003 mask:c06 ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:1df51500a75e538c
Это выглядит как запись для часов внизу!
Давайте попробуем что-нибудь с большим количеством часов, на этот раз с inotifywait
утилитой, просто наблюдая за тем, что есть /tmp
:
joel@gladstone:~$ inotifywait /tmp/* &
[4] 27862
joel@gladstone:~$ Setting up watches.
Watches established.
joel@gladstone:~$ ls -ahtlr /proc/27862/fd | grep inotify
lr-x------ 1 joel joel 64 Feb 22 22:41 3 -> anon_inode:inotify
joel@gladstone:~$ cat /proc/27862/fdinfo/3
pos: 0
flags: 00
mnt_id: 11
inotify wd:6 ino:7fdc sdev:ca00003 mask:fff ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:dc7f0000551e9d88
inotify wd:5 ino:7fcb sdev:ca00003 mask:fff ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:cb7f00005b1f9d88
inotify wd:4 ino:7fcc sdev:ca00003 mask:fff ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:cc7f00006a1d9d88
inotify wd:3 ino:7fc6 sdev:ca00003 mask:fff ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:c67f00005d1d9d88
inotify wd:2 ino:7fc7 sdev:ca00003 mask:fff ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:c77f0000461d9d88
inotify wd:1 ino:7fd7 sdev:ca00003 mask:fff ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:d77f00000053c98b
Ага! Больше записей! Итак, у нас должно быть шесть вещей /tmp
:
joel@opx1:~$ ls /tmp/ | wc -l
6
Отлично. Мой новый inotifywait
имеет одну запись в своем fd
списке (это то, что подсчитывают другие однострочники), но шесть записей в своем fdinfo
файле. Таким образом, мы можем выяснить, сколько часов использует данный fd для данного процесса, просмотрев его fdinfo
файл. Теперь, чтобы сложить его с некоторыми из вышеперечисленных, можно получить список процессов, у которых открыты часы уведомлений, и использовать их для подсчета записей в каждом fdinfo
. Это похоже на вышеприведенное, поэтому я просто дам здесь однострочник:
sudo lsof | awk '/anon_inode/ { gsub(/[urw]$/,"",$4); print "/proc/"$2"/fdinfo/"$4; }' | while read fdi; do count=$(sudo grep -c inotify $fdi); echo -e $count"\t"$fdi; done
Здесь есть некоторые толстые вещи, но основы в том, что я использую, awk
чтобы построить fdinfo
путь из lsof
выходных данных, захватывая pid и число fd, убирая флаг u / r / w из последнего. Затем для каждого построенного fdinfo
пути я подсчитываю количество inotify
строк и выводю количество и pid.
Было бы неплохо, если бы у меня были процессы, которые эти пиды представляют в одном месте, правда? Я так и думал. Так, в частности , грязных немного, я остановился на вызов dirname
дважды на fdinfo
пути , чтобы получить пакет к /proc/<pid>
, добавив /exe
к нему, а затем работает readlink
на том , что , чтобы получить имя еха процесса. Также добавьте это, отсортируйте по количеству часов и перенаправьте в файл для сохранности, и мы получим:
sudo lsof | awk '/anon_inode/ { gsub(/[urw]$/,"",$4); print "/proc/"$2"/fdinfo/"$4; }' | while read fdi; do count=$(sudo grep -c inotify $fdi); exe=$(sudo readlink $(dirname $(dirname $fdi))/exe); echo -e $count"\t"$fdi"\t"$exe; done | sort -n > watches
Запустив это без sudo, чтобы просто показать мои процессы, которые я запустил выше, я получаю:
joel@gladstone:~$ cat watches
6 /proc/4906/fdinfo/3 /usr/bin/inotifywait
1 /proc/22734/fdinfo/4 /usr/bin/tail
Отлично! Список процессов, fd, и сколько часов каждый использует, что именно то, что мне нужно.
find /proc/*/fd/* -type l -lname 'anon_inode:inotify' -print