Bash-Skript zum Überwachen des Dateiwechsels und Ausführen des Befehls


12

Ich habe einen Ordner mit einer Reihe von Unterordnern, diese Ordner wurden asciidoctormit der .adocErweiterung abgelegt .

Jedes Mal, wenn ich Änderungen an Dateien vorgenommen habe (was häufig der Fall ist), muss ich ausgeführt werden

asciidoctor -q filename.adoc

um es in das HTML-Format zu kompilieren.

Ich versuche den Prozess zu automatisieren. Bisher bin ich mit entr gekommen :

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

funktioniert aber nur mit vorhandenen Ordnern, nicht für Unterordner. Ich habe diese Variante ausprobiert, aber sie funktioniert nicht:

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

Irgendwelche Ideen, wie ich diesen automatisierten Prozess für alle Unterordner implementieren könnte?


1
Mögliches Duplikat von Wie erkennt man Dateiänderungen
Anwar

Antworten:


17

Linux bietet eine schöne Schnittstelle zum Überwachen aller Dateisystemereignisse wie Erstellen, Ändern und Entfernen von Dateien. Die Schnittstelle ist eine inotifyFamilie von Systemaufrufen. Die Userspace-Dienstprogramme, die diese Aufrufe nutzen, werden vom inotify-toolsPaket in Ubuntu bereitgestellt (verfügbar im Universum-Repository). Wenn Sie es noch nicht haben, installieren Sie es durch:

sudo apt-get install inotify-tools

inotify-toolsbietet inotifywaitund inotifywatchbinaries, wir brauchen die erste.


Sie möchten den Befehl also ausführen, asciidoctor -q some_filewenn eine .adocDatei geändert wird ( some_filewird durch diese ersetzt). Wenn sich Ihre .adocDateien im Verzeichnis befinden /foo/bar, können Sie die Überwachung einstellen:

inotifywait -qm --event modify --format '%w' /foo/bar/*.adoc
  • -qaktiviert den leisen Modus, keine Infos von inotifywaitsich

  • -m Aktiviert den Überwachungsmodus, andernfalls wird er nach dem ersten Ereignis beendet

  • --event modifyWir sind nur an modifyEreignissen interessiert , dh wenn eine Datei geändert wird. Andere mögliche Werte sind open, closeusw.

  • --format %wWir möchten nur den Dateinamen, der geändert wird, und nicht eine Reihe anderer Informationen, da wir den Dateinamen als Eingabe für einen anderen Befehl verwenden

  • /foo/bar/*.adocwird auf alle .adocDateien im /foo/barVerzeichnis erweitert


Das Obige zeigt Ihnen nun den Dateinamen, wenn einer geändert wird, um den Befehl für den Dateinamen auszuführen (vorausgesetzt, der Befehl akzeptiert Argumente über STDIN):

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

Sie können auch eine rekursive Überwachung für das Verzeichnis einrichten. Anschließend müssen Sie grepnur die gewünschten Dateien filtern. Hier setzen Sie die Uhr rekursiv ( -r) im Verzeichnis /foo/barund grepfiltern nur .adocDateien:

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

Beim Betrachten von Verzeichnissen wird der Ausgabeformatbezeichner %win den Verzeichnisnamen aufgelöst, daher müssen wir %fden Dateinamen abrufen. Beim Betrachten von Dateien %fwürde sich die Zeichenfolge leeren.

Beachten Sie, dass Sie auch inotifywaitim daemon ( -d) -Modus ausführen können, das Ganze skripten und / oder im Hintergrund ausführen und / oder mit anderen Optionen spielen können.

Sie können auch durch asciidoctoreinen anderen Befehl Ihrer Wahl ersetzen , wenn Sie möchten.

Überprüfen Sie man inotifywait, um mehr Idee zu bekommen.


Danke, es hat funktioniert. Ich habe auch etwas ähnliches für OSX. Aber ich denke, dies ist nicht der richtige Ort, um zu fragen.
Kleie

@bran Ja, IMHO gehe zu UL , du kannst dies als Referenz verwenden.
Heemayl

Tolle Antwort, nur eine kleine Korrektur. -q macht das Programm "weniger ausführlich", -qq (double q) macht es bis auf schwerwiegende Fehler völlig stumm.
Jotadepicas

4

Die Verwendung inotifywaitist der typische Ansatz, es gibt jedoch auch ein separates Dienstprogramm namens inotify-hookable, mit dem Sie nur einen Befehl ausführen können, wenn sich eine Datei (oder ein Verzeichnis) ändert:

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

Es scheint zu beenden, nachdem der Befehl einmal ausgelöst wurde. Ich sehe keine Option für kontinuierliches Beobachten, also könnten Sie etwas tun wie:

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

Beachten Sie, dass es Optionen gibt, um mehrere Dateien oder ein Verzeichnis rekursiv zu überwachen, und Optionen, um Dateien / Pfade zu ignorieren.


inotify-hookable wird nach dem Ausführen des Befehls für mich nicht beendet. Hmm
Max

inotify-hookable wird aus einem anderen Paket installiert:sudo apt-get install inotify-hookable
Bruno Silvano

2

Es gibt viele Tools, insbesondere wenn Sie Ihr Repository durchsuchen

apt-cache search monitor | grep file

Das gibt uns viele Werkzeuge. Aber du musst sie nicht testen, weil ich das getan habe.

Ich habe diese und viele andere Tools getestet:

  • inotifizieren
  • fswatch
  • Filewatch
  • Farbfeld
  • fileschanged
  • entr

Unter diesen Tools fand ich drei nützlich und zuverlässig:

  • direvent | GNU geschrieben in C.
  • iwatch | in Perl
  • fsniper

Und zwischen diesen drei ist das Direvent ohne Zweifel das beste.

Die Verwendung ist so nützlich und zuverlässig, dass ich sie für eine einfache Pipeline mit meinen Microservices verwendet habe.

direvent.conf Datei zum Anschauen

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);
}

Dies ist nur eine der Konfigurationsdateien, in denen dieser Befehl ausgeführt wird, wenn sich das Schreiben ändert. Dies kann auch ein Skript sein.

Keine Notwendigkeit, whileSchleife oder andere Sachen zu verwenden.


Eigenschaften

  • rekursiv ein Verzeichnis beobachten
  • kann als Daemon im Vordergrund oder im Hintergrund ausgeführt werden
  • tragbar. Ich habe es in Ubuntu sowie CentOS7 Server
  • Dateinamenbericht
  • Regex zur Unterstützung des Dateiabgleichs
  • Mulit-File-Watching (mehr als nur einen Dateityp)
  • Befehlsausführung synchronisieren (wenn wir Multi-Watcher haben)
  • Syslog-Behandlung (Protokoll in Syslog, wenn wir wollen)
  • Einfaches und gutes Design für CLI- und Konfigurationsdateien

Entwickelt von Sergey Poznyakoff .


Installieren

sudo apt install direvent

Die Installation mit dem Quellcode ist jedoch recht einfach und unkompliziert, sodass Sie die letzte Version erhalten (derzeit: 5.1).


-3

Nun, ich empfehle Folgendes.

#!/bin/bash
#Script
for SRC in *.adoc; 
      do
      asciidoctor -q $SRC
  done

1
OP will den Befehl nur ausführen, wenn Änderungen vorgenommen werden ..
heemayl
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.