inotifywait 没有响应 /proc/mounts 中的更改

inotifywait 没有响应 /proc/mounts 中的更改

我正在尝试获取有问题的 sshfs 安装状态的通知

我尝试过两个 bash 脚本

while inotifywait -e modify /proc/mounts; do
  echo "modified" 
done

inotifywait -m /proc/mounts |
while read event; do
  echo $event
done

为了进行测试,我正在运行以下序列,但这些脚本都没有响应。

 stephen@asus:~/log$ sudo umount /mnt/lexar
 stephen@asus:~/log$ sshfs michigan:/home/stephen/ /mnt/lexar
 stephen@asus:~/log$ sudo umount /mnt/lexar
 stephen@asus:~/log$ sshfs michigan:/home/stephen/ /mnt/lexar
 stephen@asus:~/log$ grep lexar /proc/mounts
 michigan:/home/stephen/ /mnt/lexar fuse.sshfs rw,nosuid,nodev,relatime,user_id=1000,group_id=1000 0 0
 stephen@asus:~/log$ sudo umount /mnt/lexar
 stephen@asus:~/log$ grep lexar /proc/mounts

答案1

inotify不适用于 proc 文件系统。尽管它们可能看起来像常规文件,但 proc 文件系统中的文件不包含任何静态数据——当您读取它们时,内核会动态地生成数据。例如,/proc/mounts=> 的/proc/self/mounts大小为 0,但是当您读取它时,它神奇地恰巧含有某种东西。

/proc/self/mounts/proc/self/mountinfo可轮询的-- 您可以select(2)poll(2)在特殊情况下使用它。根据proc(5)联机帮助页:

/proc/[pid]/mounts(自 Linux 2.4.19 起)

该文件列出了当前在进程的挂载命名空间中挂载的所有文件系统(请参阅 参考资料mount_namespaces(7))。该文件的格式记录在fstab(5).

从内核版本 2.6.15 开始,此文件是可轮询的:打开文件进行读取后,此文件中的更改(即文件系统挂载或卸载)会导致select(2)将文件描述符标记为具有异常情况,并poll(2)标记epoll_wait(2)该文件具有优先事件 ( POLLPRI)。

[这同样适用于/proc/[pid]/mountinfo]

我认为没有任何方法可以从 shell 中做到这一点。不过,您可以从 执行此操作perl

#! /usr/bin/perl
use strict;
my $mf = "/proc/self/mountinfo";
open my $mh, "<$mf" or die "open <$mf: $!";
vec(my $ebits, $mh->fileno, 1) = 1;
while(1){
        select(undef, undef, my $e = $ebits, undef) == -1 and die "select: $!";
        print "some mount or umount happened\n";
}

一个更有用的例子,它也显示了什么更改于/proc/self/mountinfo

#! /usr/bin/perl
use strict;
my $mf = "/proc/self/mountinfo";
open my $mh, "<$mf" or die "open <$mf: $!";
vec(my $ebits, $mh->fileno, 1) = 1;
sub read_mounts {
        seek $mh, 0, 0 or die "seek: $!";
        my ($h, $i); $$h{$_} = ++$i while <$mh>; return $h;
}
for(my ($old, $new) = read_mounts;; $old = $new) {
        select undef, undef, my $e = $ebits, undef or die "select: $!";
        $new = read_mounts;
        for(keys %$new){
                if(exists $$old{$_}){ delete $$old{$_} }
                else{ print '+ ', $_ }
        }
        print '- ', $_ for keys %$old;
}

相关内容