Dlaczego inotifywatch nie wykrywa zmian w dodanych plikach?

14

Próbuję monitorować mój /tmpfolder pod kątem zmian, używając inotifywatch:

sudo inotifywatch -v -r /tmp

Po utworzeniu kilku plików ( touch /tmp/test-1 /tmp/test-2) kończę inotifywatch(przez Ctrl- Cco pokazuje mi następujące statystyki:

Establishing watches...
Setting up watch(es) on /tmp
OK, /tmp is now being watched.
Total of 39 watches.
Finished establishing watches, now collecting statistics.
total  attrib  close_write  open  create  filename
8      2       2            2     2       /tmp/

Dane wyjściowe drukują tylko statystyki, ale nie pliki, których się spodziewałem (jak tutaj lub tutaj ). Próbowałem różne rodzaje dostępu (poprzez cat, mktempetc.), ale jest to samo.

Przegapiłem coś? To dlatego, że jestem na VPS i coś zostało ograniczone?

System operacyjny: Debian 7.3 (inotify-tools) na VPS

kenorb
źródło

Odpowiedzi:

14

Wynika to ze sposobu użytkowania inotifywatchi sposobu działania samego narzędzia. Po uruchomieniu inotifywatch -r /tmpzaczniesz oglądać /tmpi wszystkie pliki, które już w nim są. Po utworzeniu wewnątrz pliku /tmp, metadane katalog jest aktualizowana zawierać numer i-węzła nowego pliku, co oznacza, że zmiana dzieje się na /tmpnie /tmp/test-1. Dodatkowo, ponieważ /tmp/test-1nie było go tam po inotifywatchuruchomieniu, nie ma inotifyna nim zegarka. Oznacza to, że żadne zdarzenie, które nastąpi w pliku utworzonym po umieszczeniu zegarków, nie zostanie wykryte . Możesz to lepiej zrozumieć, jeśli zobaczysz to sam:

$ inotifywatch -rv /tmp &
Total of n watches.
$ cat /sys/kernel/debug/tracing/trace | grep inotifywatch | wc -l
n

Jeśli włączyłeś mechanizm śledzeniainotify_add_watch(2) , ostatnie polecenie poda liczbę ustawionych zegarków inotifywatch. Liczba ta powinna być taka sama jak podana przez inotifywatchsiebie. Teraz utwórz plik w środku /tmpi sprawdź ponownie:

$ inotifywatch -rv /tmp &
Total of n watches.
$ touch /tmp/test1.txt
$ cat /sys/kernel/debug/tracing/trace | grep inotifywatch | wc -l
n

Liczba nie wzrośnie, co oznacza, że ​​nowy plik nie jest oglądany. Pamiętaj, że zachowanie jest inne, jeśli zamiast tego utworzysz katalog:

$ inotifywatch -rv /tmp &
Total of n watches.
$ mkdir /tmp/test1
$ cat /sys/kernel/debug/tracing/trace | grep inotifywatch | wc -l
n + 1

Wynika to ze sposobu działania -rprzełącznika :

-r, --recursive: [...] Jeśli w obserwowanych katalogach zostaną utworzone nowe katalogi, zostaną one automatycznie obejrzane.

Edit: Mam trochę mylić między dwoma przykładami, ale w pierwszym przypadku , zegarki są prawidłowo umieszczone, ponieważ rozmowy użytkowników inotifywatchna ~/*(co jest rozszerzona, patrz komentarz don_crissti tutaj ). Katalog domowy jest również oglądany, ponieważ ~/.*zawiera ~/.. Teoretycznie powinien on także zawierać ~/.., co w połączeniu z -rprzełącznikiem powinno skutkować obserwowaniem całego systemu.

Jednakże, to jest możliwe, aby uzyskać nazwę pliku wywołując utworzyć zdarzenie w oglądanym katalogu, ale zgaduję inotifywatchnie odzyskać te informacje (jest zapisany trochę głębiej niż nazwa katalogu). inotify-toolsudostępnia inne narzędzie o nazwie inotifywait, które może zachowywać się podobnie inotify-watch, i zapewnia więcej opcji wyjściowych (w tym %f, czego szukasz tutaj):

inotifywait -m --format "%e %f" /tmp

Ze strony podręcznika :

--format <fmt>Dane wyjściowe w formacie określonym przez użytkownika przy użyciu składni podobnej do printf. [...] Obsługiwane są następujące konwersje:

%f: gdy zdarzenie wystąpi w katalogu, zostanie ono zastąpione nazwą pliku, który spowodował wystąpienie zdarzenia .

%e: zastąpione zdarzeniem (zdarzeniami), które miały miejsce, oddzielone przecinkami.

Poza tym -mopcja (monitor) będzie inotifywaitdziałać po pierwszym zdarzeniu, co spowoduje odtworzenie zachowania podobnego do tego inotifywatch.

John WH Smith
źródło
1
.bashrcna przykład @ serverfaultnie pojawiają się w statystykach, ponieważ użytkownik monitoruje swój katalog domowy rekurencyjnie ale ponieważ path/.*rozszerza się iw efekcie zegarek jest ustawiony dla wszystkich .files poniżej path/( .bashrcw zestawie). Polecenie używane przez OP nigdy nie wypisuje nazw plików, ponieważ zegarki są ustawione dla /tmpi wszystkich podkatalogów, dlatego statystyki będą dotyczyły tylko /tmpi ich podkatalogów (tzn. Zobaczysz, że pliki zostały otwarte / przeniesione / itp., Ale nie powie ci nazwy).
don_crissti
@don_crissti Ups, pomieszałem dwa przykłady podane przez OP. Zredagowałem swoją odpowiedź, dzięki!
John WH Smith
Dzięki, to było przydatne. Oto moje polecenie, aby wyświetlić zawartość wszystkich nowo utworzonych plików test * w /tmp: inotifywait -m --format "%f" /tmp | grep --line-buffered ^test | xargs -L1 -I% sudo cat /tmp/% 2> /dev/null.
kenorb
Ponadto: „ Oznacza to, że każde zdarzenie, które wystąpi w pliku utworzonym po umieszczeniu zegarków, nie zostanie wykryte. ” Każde zdarzenie (nawet tworzenie pliku) BĘDZIE wykryte, ponieważ zegarek JUŻ jest ustawiony dla zawierającego go katalogu i jest to odzwierciedlone w statystykach dla tego konkretnego katalogu. Zobacz inotifywatchdane wyjściowe w pytaniu OP: 2 createzdarzenia są tam (więc zostały wykryte), ale ponieważ inotifywatchogląda katalog (+ dowolne podkatalogi) statystyki dotyczą tylko tego / tych katalogów.
don_crissti
1
Nie sądzę, abyśmy byli tutaj na tej samej długości fali ... man inotify: When a directory is monitored, inotify will return events for the directory itself, and for files inside the directory.Ponadto man inotifywatchjasne jest, które zdarzenia są oglądane: EVENTS>> ... Dostęp do obejrzanego pliku lub pliku w obserwowanym katalogu był dostępny / zamknięty / otwarty / itp. (oznacza w tym zdarzenia „występujące w pliku” ). Zdarzenia dla pliku utworzonego po ustawieniu zegarka w katalogu macierzystym BĘDĄ wykryte i odzwierciedlone w inotifywatchstatystykach (NIE będzie podawać, dla których plików wystąpiły te zdarzenia).
don_crissti