Skrypt Bash do monitorowania zmian plików i wykonywania poleceń

12

Mam folder z wieloma podfolderami, foldery te zostały asciidoctorsformatowane z .adocrozszerzeniem.

Za każdym razem, gdy wprowadzam zmiany w plikach (co często bywa), muszę uruchomić

asciidoctor -q filename.adoc

aby skompilować go do formatu HTML.

Próbuję zautomatyzować ten proces. do tej pory korzystałem z tego za pomocą entr :

ls *.adoc | entr asciidoctor -q *.adoc

ale działa tylko z istniejącym folderem, a nie dla podfolderów. Wypróbowałem tę odmianę, ale nie działa:

find . -name '*.adoc' | entr asciidoctor -q *.adoc

Wszelkie pomysły, w jaki sposób mogę zaimplementować ten zautomatyzowany proces dla wszystkich podfolderów?

otręby
źródło
1
Możliwy duplikat Wykrywania zmian w plikach
Anwar

Odpowiedzi:

17

Linux zapewnia ładny interfejs do monitorowania wszystkich zdarzeń w systemie plików, takich jak tworzenie, modyfikowanie, usuwanie plików. Interfejs to inotifyrodzina wywołań systemowych, narzędzia przestrzeni użytkownika wykorzystujące te wywołania są dostarczane przez inotify-toolspakiet w Ubuntu (dostępny w repozytorium wszechświata). Jeśli jeszcze go nie masz, zainstaluj:

sudo apt-get install inotify-tools

inotify-toolszapewnia inotifywaiti inotifywatchpliki binarne, potrzebujemy pierwszego.


Więc chcesz uruchomić polecenie, asciidoctor -q some_filegdy dowolny .adocplik zostanie zmodyfikowany ( some_filezostanie zastąpiony tym), jeśli tak, zakładając, że twoje .adocpliki znajdują się w katalogu /foo/bar, możesz ustawić zegarek:

inotifywait -qm --event modify --format '%w' /foo/bar/*.adoc
  • -qwłącza tryb cichy, brak informacji od inotifywaitsiebie

  • -m włącza tryb monitorowania, w przeciwnym razie wyjdzie po pierwszym zdarzeniu

  • --event modify, interesuje nas tylko modifyzdarzenie, tj. modyfikacja pliku. Inne możliwe wartości to open, closeetc.

  • --format %w, chcemy tylko zmodyfikowanej nazwy pliku, a nie innych informacji, ponieważ będziemy używać nazwy pliku jako danych wejściowych do innego polecenia

  • /foo/bar/*.adoczostanie rozwinięty do wszystkich .adocplików w /foo/barkatalogu


Teraz powyższe pokaże nazwę pliku przy każdej modyfikacji, teraz, aby uruchomić polecenie na nazwie pliku (zakładając, że polecenie przyjmuje argumenty przez STDIN):

inotifywait -qm --event modify --format '%w' /foo/bar/*.adoc | asciidoctor -q

Możesz także ustawić zegarek rekursywny w katalogu, a następnie będziesz musiał użyć grepdo filtrowania tylko wybranych plików. Tutaj ustawiam rekursywnie ( -r) na katalog /foo/bari używamy grepdo filtrowania tylko .adocplików:

inotifywait -qrm --event modify --format '%w%f' /foo/bar | grep '\.adoc$' | asciidoctor -q

Podczas oglądania katalogów specyfikator formatu wyjściowego %wrozpoznaje nazwę katalogu, więc musimy %fuzyskać nazwę pliku. Podczas oglądania plików, %fpostanawia opróżnić ciąg.

Zauważ, że możesz także uruchomić inotifywaitw -dtrybie daemon ( ), możesz także napisać skrypt i / lub uruchomić w tle i / lub grać z innymi opcjami.

Możesz także zastąpić asciidoctordowolne inne polecenie, jeśli chcesz.

Sprawdź, man inotifywaitaby uzyskać więcej pomysłów.

heemayl
źródło
Dzięki, działało. Mam też coś podobnego do OSX. ale myślę, że nie jest to właściwe miejsce, aby zapytać.
otręby
@bran Tak, IMHO przejdź do UL , możesz użyć tego jako odniesienia.
heemayl
Świetna odpowiedź, tylko drobna korekta. -q powoduje, że program jest „mniej gadatliwy”, -qq (podwójne q) czyni go całkowicie cichym, z wyjątkiem błędów krytycznych.
jotadepicas,
4

Używanie inotifywaitjest typowym podejściem, ale istnieje także osobne narzędzie, inotify-hookablektóre pozwala na uruchomienie polecenia, gdy zmienia się plik (lub katalog):

inotify-hookable -f filename.adoc -c 'asciidoctor -q filename.adoc'

Wydaje się, że kończy działanie po jednokrotnym uruchomieniu polecenia; Nie widzę opcji ciągłego oglądania, więc możesz zrobić coś takiego:

while true; do
    inotify-hookable -f filename.adoc -c 'asciidoctor -q filename.adoc'
    echo "== $(date) : executed, continuing to monitor..."
done

Uwaga: istnieją opcje monitorowania kilku plików lub katalogu rekurencyjnie oraz opcje ignorowania plików / ścieżek.

Michał
źródło
Program inotify-hookable nie kończy działania po uruchomieniu polecenia dla mnie. Hmm
maks.
Inotify-hookable jest instalowany z innego pakietu:sudo apt-get install inotify-hookable
Bruno Silvano,
3

Istnieje wiele narzędzi, szczególnie jeśli przeszukujesz swoje repozytorium

apt-cache search monitor | grep file

co daje nam wiele narzędzi. Ale nie musicie ich testować, ponieważ to zrobiłem.

Przetestowałem te narzędzia i wiele innych:

  • inotify
  • fswatch
  • filtr plików
  • próbka
  • pliki zmienione
  • entr

Wśród tych narzędzi znalazłem trzy z nich przydatne i niezawodne:

  • Direvent | GNU napisane w C
  • iwatch | w Perlu
  • fsniper

A między tymi trzech, direvent jest najlepszy bez wątpienia.

Jest tak użyteczny i niezawodny w użyciu, że użyłem go do prostego potoku z moimi mikrousługami, które mam.

direvent.conf plik do oglądania

syslog {
    facility local0;
    tag "direvent";
    print-priority yes;
}

watcher {
    path /var/www/html/ir/jsfun/build/react recursive;
    file "*.js";
    event write;
    command "/usr/bin/xdotool search --onlyvisible  --class firefox key F5";
    option (stdout, stderr, wait);
}

Jest to tylko jeden z plików konfiguracyjnych, w których mam, w których za każdym razem, gdy zachodzi zmiana zapisu, to polecenie jest wykonywane - co może być również skryptem .

Nie musisz używać whilepętli ani innych rzeczy.


funkcje

  • rekurencyjnie ogląda katalog
  • może być uruchamiany na pierwszym planie lub w tle jako demon
  • przenośny. Mam go w Ubuntu, a także na serwerze CentOS7
  • raport nazwy pliku
  • Wyrażenie regularne w celu obsługi dopasowania plików
  • oglądanie wielu plików (obejrzyj więcej niż jeden typ pliku)
  • zsynchronizuj wykonywanie poleceń (jeśli mamy wielu obserwatorów)
  • obsługa syslog (zaloguj się do syslog, jeśli chcemy)
  • łatwy i dobry projekt interfejsu CLI i plików konfiguracyjnych do pracy

Opracowany przez Sergey Poznyakoff .


Instalowanie

sudo apt install direvent

Ale zainstalowanie go za pomocą kodu źródłowego jest dość łatwe i łatwe, co daje ostatnią wersję (obecnie jest to: 5.1).

Shakiba Moshiri
źródło
-3

Cóż, polecam następujące.

#!/bin/bash
#Script
for SRC in *.adoc; 
      do
      asciidoctor -q $SRC
  done
SAGAR Nair
źródło
1
OP chce uruchomić polecenie tylko po wprowadzeniu modyfikacji.
heemayl