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

inotifyproc 파일 시스템에는 적용할 수 없습니다. 일반 파일처럼 보이지만 proc 파일 시스템의 파일에는 정적 데이터가 포함되어 있지 않습니다. 커널은 파일을 읽을 때 동적으로 데이터를 생성합니다. 예를 들어 /proc/mounts=> /proc/self/mounts의 크기는 0이지만 이를 읽으면마술적으로무언가가 포함되어 있는 경우가 있습니다.

하지만 /proc/self/mounts그리고 /proc/self/mountinfo폴링 가능-- 특별한 상황에서 사용할 select(2)수 있습니다. poll(2)~에 따르면proc(5)맨페이지:

/proc/[pid]/mounts(리눅스 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;
}

관련 정보