Spotkałem się z następującym problemem: w momencie wykonania modyfikacji pewnych plików lub katalogów chciałem wykonać określoną akcję. W moim przypadku chodzi o automatyczne utworzenie pliku PDF na podstawie plików źródłowych stworzonych w LaTeXu.
W przypadku Linuksa mamy do dyspozycji podsystem jądra o nazwie inotify, który pozwala na powiadamianie aplikacji o różnych zmianach mających miejsce w ramach systemu plików. Ponieważ jest to moduł pracujący w przestrzeni jądra systemu, nie ma potrzeby skanowania systemu plików w celu poszukiwania zmian. Wystarczy jedynie zarejestrować aplikację, podać jakie zdarzenia i pliki (czy też katalogi) mają być monitorowane i o resztę będzie się troszczyć sam systemu operacyjny.
Oczywiście, to że jądro udostępnia jakąś usługę i istnieją odpowiednie biblioteki systemowe nie rozwiązuje problemu (chyba że piszemy własną aplikację). Znalazłem dwie aplikacje, które działają w przestrzeni użytkownika i pozwalają na wykorzystanie inotify
:
- incron – narzędzie to przypomina trochę crona, do działania wymaga zainstalowanego serwera oraz klienta w którym będzie można definiować reguły monitorowania i postępowania z plikami, pozwala ono na zdefiniowanie zarówno co ma być monitorowane o raz jakie akcje (np. jakie skrypty uruchomić) w momencie wykrycia zmian w systemie plików
- inotify-tools – dwa polecenie, z których jedno pozwoli wyświetlić informacje statystyczne o modyfikacjach w systemie plików (
inotifywatch
), a drugie wyświetli informacje o zmodyfikowanych plikach (inotifywait
)
W moim przypadku incron
jest za dużym rozwiązaniem, nie potrzebują także ciągłego monitorowania wybranych katalogów, jedynie na czas pracy z LaTeXem. Idealnym rozwiązaniem okazało się użycie polecenia inotifywait
. Nasłuchuje ono na zamiany w wybranych plikach czy katalogach i w momencie ich wystąpienia kończy swoje działanie jednocześnie wyświetlając informacje o tym, co zostało zmienione. Posiada także możliwość pracy w trybie ciągłego nasłuchiwania, czyli informuje nas o zmianach bez kończenia działania, ale tutaj funkcja ta nie będzie potrzebna.
Więc czas na konkrety: instalacja pakietu w Ubuntu:
Teraz czas na mały skrypt, który będzie odpowiedzialny za uruchomienie nasłuchiwania oraz wykonywanie odpowiednich poleceń:
1 2 3 4 5 6 7 8 9 | #!/bin/bash MONITOR_COMMAND="inotifywait -q -e modify --format '%w%f' --excludei '.*temp.*' ." while true do OUTPUT=`$MONITOR_COMMAND` && \ pdflatex -output-directory=out main.tex done; |
Skrypt robi:
- linia 3 – definicja wywoływania polecenia
inotifywait
:-q
– tryb cichy, nie wyświetla zbędnych informacji-e modify
– lista monitorowanych zdarzeń na plikach, tutaj tylko modyfikacja plików, ale można monitorować np. dostęp do nich, tworzenie, usuwanie, przenoszenie, zmiany metadanych--format '%w%f'
– format, w jakim ma być wyświetlona informacje o tym co się zmieniło, w tym przypadku nazwa pliku wraz z katalogiem, w którym się on znajduje--excludei '.*temp.*'
– jakich plików nie brać pod uwagę
- linia 5 – rozpoczęcie pętli, nieskończonej
- linia 7 – wywołanie polecenia
inotifywait
, polecenie to skończy działanie dopiero jak wykryje jakieś zmiany w monitorowanych plikach - linia 8 – wywołanie akcji, w moim przypadku kompilacja raportu
W zmiennej $OUTPUT
znajdzie się lista zmodyfikowanych plików, więc w razie potrzeb można na niej wykonać określone akcje.
Skrypt ten będzie działał w nieskończoność, do momentu przerwania jego wykonywania. Dzięki niemu można mieć podgląd wygenerowanych dokumentów LaTeX prawie w czasie rzeczywistym.