我遇到了这个问题,这些答案都没有给您答案“ 每个进程当前使用多少只手表?”。一线便能为您提供打开实例的数量,这只是故事的一部分,而跟踪信息仅对于查看正在打开的新手表有用。
TL; DR:这将为您提供一个文件,其中包含打开的inotify
实例列表以及它们拥有的监视数量,以及产生它们的pid和二进制文件,并按监视数量降序排列:
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
在一个测试文件上运行了一个文件,并查看了它打开的fd:
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是我们要调查的fd。让我们看看其中的含义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
文件中有六个条目。因此,我们可以通过查询fdinfo
文件来确定给定进程的给定fd使用了多少手表。现在将其与上面的一些内容放在一起,以获取已打开通知手表的进程列表,并使用该进程对每个表中的条目进行计数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。
但是,如果我在同一个位置上具有这些pid所代表的进程,那会很好,对吗?我是这么想的。因此,在一个特别凌乱一点,我定居在呼吁dirname
上两次fdinfo
获得包到路径/proc/<pid>
,加入/exe
到它,然后运行readlink
上是获得进程的exe文件名。同样将其扔到那里,按手表数量排序,然后将其重定向到文件中以进行安全保存,我们得到:
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