Ciągłe wykrywanie nowych plików za pomocą narzędzi inotify w wielu katalogach rekurencyjnie

17

Właśnie zainstalowałem narzędzia inotify. Chciałbym ciągle wykrywać nowe pliki za pomocą narzędzi powiadomień w wielu katalogach rekurencyjnie i wysyłać wiadomości e-mail za pomocą Postfiksa. Prawdopodobnie mogę obsłużyć wysłać e-mail za pomocą części Postfix. Próbuję tylko znaleźć najlepszy sposób, aby się tym zająć, próbując wykryć nowe pliki. Ponieważ czasami dodaje się wiele plików jednocześnie.

David Custer
źródło

Odpowiedzi:

39

inotifywait (część narzędzi inotify ) jest właściwym narzędziem do osiągnięcia celu, nie ma znaczenia, że ​​kilka plików jest tworzonych w tym samym czasie, wykrywa je.

Oto przykładowy skrypt:

#!/bin/sh
MONITORDIR="/path/to/the/dir/to/monitor/"
inotifywait -m -r -e create --format '%w%f' "${MONITORDIR}" | while read NEWFILE
do
        echo "This is the body of your mail" | mailx -s "File ${NEWFILE} has been created" "[email protected]"
done

inotifywait użyje tych opcji.

-m do monitorowania katalogu w nieskończoność, jeśli nie użyjesz tej opcji, po wykryciu nowego pliku skrypt się zakończy.

-r będzie rekurencyjnie monitorować pliki (jeśli jest dużo katalogów / plików, wykrycie nowo utworzonych plików może chwilę potrwać)

-e create to opcja określająca zdarzenie, które ma być monitorowane, aw twoim przypadku powinno być utworzone, aby dbać o nowe pliki

--format '% w% f' wydrukuje plik w formacie /complete/path/file.name

„$ {MONITORDIR}” to zmienna zawierająca ścieżkę monitorowania, którą zdefiniowaliśmy wcześniej.

W przypadku utworzenia nowego pliku, inotifywait wykryje go i wydrukuje dane wyjściowe (/complete/path/file.name) do potoku i jednocześnie przypisze je do zmiennej NEWFILE .

Wewnątrz pętli while zobaczysz sposób wysłania wiadomości na twój adres za pomocą narzędzia mailx, które powinno działać poprawnie z lokalnym MTA (w twoim przypadku Postfix).

Jeśli chcesz monitorować kilka katalogów, inotifywait nie pozwala na to, ale masz dwie opcje, utwórz skrypt dla każdego katalogu do monitorowania lub utwórz funkcję w skrypcie, coś takiego:

#!/bin/sh
MONITORDIR1="/path/to/the/dir/to/monitor1/"
MONITORDIR2="/path/to/the/dir/to/monitor2/"
MONITORDIRX="/path/to/the/dir/to/monitorx/"    

monitor() {
inotifywait -m -r -e create --format "%f" "$1" | while read NEWFILE
do
        echo "This is the body of your mail" | mailx -s "File ${NEWFILE} has been created" "[email protected]"
done
}
monitor "$MONITORDIR1" &
monitor "$MONITORDIR2" &
monitor "$MONITORDIRX" &
sahsanu
źródło
Zapomniałem dodać kilka wyjaśnień dotyczących poleceń użytych w przykładowym skrypcie, który jest powodem edycji mojej odpowiedzi ... Dodałem również skrypt na wypadek, gdyby op chciał monitorować kilka katalogów. Jeśli chodzi o narzędzie inotifywait, nie można odpowiedzieć na pytanie bez wzmianki, ponieważ op używa narzędzi inotify. Nawiasem mówiąc, jestem tutaj nowicjuszem, więc muszę się dużo nauczyć na temat netykiety, więc przepraszam, jeśli moja odpowiedź pokrywa się z twoją, nie było to, czego chcę, chcę tylko dać pełną odpowiedź na temat op. Jeszcze raz przepraszam.
sahsanu,
Nie ma problemu i witamy w SU. Nauka netykiety jest zwykle trudna, ponieważ nie jest tak naprawdę nigdzie zdefiniowana.
harrymc,
4
@ sahsanu Nie zgadzam się co do całej tej „netykiety”. Każda osoba odpowiada na pytanie z własnej perspektywy. Odpowiedzi nie pokrywają się, ani nie napisano odpowiedzi, która została przepisana. Nie jest możliwe, aby odpowiedzi różniły się w ten sposób, gdy pytanie jest tak konkretne. Dziękuję bardzo za poświęcenie czasu na szczegółowe udzielenie odpowiedzi na pytanie. To pomogło bardziej niż wiesz, dla kogoś takiego jak ja, który dopiero się o tym wszystkim uczy. Uratowałeś mi niezliczone godziny.
David Custer,
1
@harrymc Netiquetta jest zdefiniowany tutaj.
David Custer,
Netykiety w zmieniającym się środowisku nie można absolutnie zdefiniować. Na tej stronie zwyczajowo nie powiela się odpowiedzi, chyba że są źle napisane, a nawet wtedy zaleca się ich poprawienie poprzez edycję. W demokratycznej społeczności zawsze masz prawo nie zgodzić się z tym. @sahsanu mógł uniknąć mojej uwagi, odwołując się do mojej poprzedniej odpowiedzi, pokazując swój skrypt, który i tak zyskałby twoją aprobatę. Tak zrobiłbym na jego miejscu i to jest moja netykieta, którą, jak sądzę, dzielę się z innymi (ale oczywiście nie ze wszystkimi).
harrymc,
8

Użyj inotifywait , na przykład:

inotifywait -m /path -e create -e moved_to |
    while read path action file; do
        echo "The file '$file' appeared in directory '$path' via '$action'"
        # do something with the file
    done

Więcej informacji i przykładów znajduje się w artykule
Jak używać narzędzi inotify do wyzwalania skryptów w zdarzeniach systemu plików .

harrymc
źródło
1
Jeśli ktoś tego użyje i skonwertuje zmienne z przeczytanych wielkimi literami, nie będziesz mógł przez chwilę uruchamiać niektórych poleceń. Wynika to z tego, że nadpisałeś zmienną $ PATH.
Savageman
2
@ Savageman Używanie nazw zmiennych pisanych wielkimi literami do własnych zmiennych jest zdecydowanie odradzane właśnie z tego powodu. Nazwy zmiennych pisane wielkimi literami są zarezerwowane do użytku systemowego; twoje własne zmienne powinny używać małych liter.
tripleee
@tripleee Dzięki za informację, nie będę już używać wielkich liter :)
Savageman
0

W przypadku kilku katalogów możesz to zrobić:

#!/bin/bash


monitor() {
  inotifywait -m -r -e attrib --format "%w%f" --fromfile /etc/default/inotifywait | while read NEWFILE
  do
     echo "This is the body of your mail" | mailx -s "File ${NEWFILE} has been created" "[email protected]"
  done
          }


monitor &

Oto przykładowa lista folderów w pliku /etc/default/inotifywait /etc/default/inotifywait

/home/user1
/path/to/folder2/
/some/path/
Konstantin Frank
źródło