Chcę automatycznie uruchamiać skrypt za każdym razem, gdy nowe pliki są kopiowane do określonego katalogu. Innymi słowy, czy jest sposób w Linuksie, aby „obserwować” katalog zmian, a następnie uruchomić coś w odpowiedzi na zmianę?
Chcę automatycznie uruchamiać skrypt za każdym razem, gdy nowe pliki są kopiowane do określonego katalogu. Innymi słowy, czy jest sposób w Linuksie, aby „obserwować” katalog zmian, a następnie uruchomić coś w odpowiedzi na zmianę?
Odpowiedzi:
Jeśli masz szczęście wystarczy być na dystrybucji Debiana opartej apt-get install dnotify
. Inne dystrybucje prawdopodobnie mają coś podobnego - poszukaj dnotify
nazwy.
dnotify to prosty program oparty na API dnotify API jądra Linuksa 2.4.19 +. dnotify może wykonać określone polecenie za każdym razem, gdy zmienia się zawartość określonego katalogu. Jest uruchamiany z wiersza poleceń i przyjmuje dwa argumenty: jeden lub więcej katalogów do monitorowania i polecenie do wykonania przy każdej zmianie katalogu. Opcje kontrolują, jakie zdarzenia mają być uruchamiane: kiedy plik został odczytany w katalogu, kiedy został utworzony, usunięty i tak dalej.
Jeśli chcesz poradzić sobie z tym w swoim własnym programie, dnotify to także interfejs API, którego chcesz użyć.
emerge inotify-tools
Możesz uruchomić skrypt za pomocą narzędzi inotify, coś takiego. Będzie obserwował katalog pod kątem zmian w zmodyfikowanych plikach, nowych i usuniętych plikach, a następnie wykona skrypt.
#!/bin/sh
while inotifywait -e modify -e create -e delete /home/me/code; do
rsync [options] /home/me/code/ /media/nfs/code/
done
myślę, że incron jest w zasadzie tym, czego chcesz. Używa inotify jako mechanizmu powiadamiania (który, jak zauważyli inni, zastępuje dnotify), ale nie wymaga skryptu, który działa w sposób ciągły, używając inotifywait lub podobnego (choć oczywiście demon incron cały czas działa). Ogólnosystemowe „crontabs” i „crontabs” użytkownika są obsługiwane w podobny sposób jak standardowy cron, ale zamiast określania czasów jako wyzwalaczy, używane są zdarzenia inotify oraz nazwy plików / katalogów.
incron jest spakowany dla wielu dystrybucji, w tym, jak sądzę, Ubuntu i Debian.
entr jest najprostszym i najbardziej składalnym narzędziem do powiadamiania o plikach, jakie widziałem. Jego użycie jest zoptymalizowane do oglądania plików, a nie katalogów, ale może również rozwiązać twoją sprawę.
Aby wykryć i działać na dodanym pliku, połącz go z innymi narzędziami, takimi jak np make
. entr
nie wysyła nazwy ani nic podobnego, po prostu uruchamia to, co kazałeś uruchomić.
Aby sprawdzić dodane pliki w katalogu:
## entr exits with rc=0 when terminated
## rc=1 when watched files go away or don't exist to begin with
## rc=2 when new files arrive in watched directories
until echo /path/to/directory_to_watch | entr -d do_stuff
do sleep 1; done
Jeśli chcesz działać również w przypadku zmiany istniejącego pliku:
## Here's why it comes in handy that entr exits when new files are added --
## find gets re-run.
until find /path/to/directory_to_watch/ -path /path/to/directory_to_watch/* |
entr -d do_stuff
do sleep 1; done
... i tu przydaje się mechanizm pętli, ponieważ find
wyrażenie zostanie uruchomione ponownie, jeśli plik zostanie dodany.
Jeśli chcesz poprawić obsługę błędów i upewnić się, że wszystko działa tylko raz dla dodanego / usuniętego pliku, robi się nieco dziwacznie, ale w tych prostych przypadkach jest genialny.
EDYCJA: Jeśli chcesz to zrobić na poziomie systemu, na przykład incron , po prostu dodaj skrypt do swojego ulubionego menedżera procesów (takiego jak s6 , runit , systemd lub sysvinit i pomiń pętlę:
#!/bin/bash
exec entr -d do_stuff < <(find /path/to/directory_to_watch/ -path /path/to/directory_to_watch/*)
Funkcje exec
oraz proces podstawiania ( <(...)
) są ważne podczas uruchamiania z menedżera procesów, aby poprawnie obsługiwać sygnalizację (tj. Aby usunąć powłokę z drogi).