Shell-Script

inotifywait 未響應 /proc/mounts 中的更改

  • March 3, 2020

我正在嘗試獲取有問題的 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

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]

我認為沒有任何方法可以從外殼中做到這一點。但是,您可以從 執行此操作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;
}

引用自:https://unix.stackexchange.com/questions/570981