Я зіткнувся з цією проблемою, і жоден із цих відповідей не дає відповіді "скільки годин використовує кожен процес?" Усі однолінійки дають вам кількість відкритих екземплярів , що є лише частиною історії, а інформацію про сліди корисно лише для того, щоб відкрити нові годинники.
TL; DR: Ви отримаєте файл із переліком відкритих inotify
примірників та кількість годин, які вони мають, а також підручники та бінарні файли, які їх породили, відсортовані у порядку зменшення за кількістю перегляду:
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
Запустивши це без судо, щоб просто показати свої процеси, які я запустив вище, я отримую:
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