GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Wie führe ich einen Befehl aus, wenn sich eine Datei ändert?

Ganz einfach, mit inotifywait (installieren Sie den inotify-tools Ihrer Distribution Paket):

while inotifywait -e close_write myfile.py; do ./myfile.py; done

oder

inotifywait -q -m -e close_write myfile.py |
while read -r filename event; do
  ./myfile.py         # or "./$filename"
done

Das erste Snippet ist einfacher, hat aber einen erheblichen Nachteil:Es werden Änderungen übersehen, die während inotifywait durchgeführt wurden nicht läuft (insbesondere während myfile läuft). Das zweite Snippet hat diesen Fehler nicht. Beachten Sie jedoch, dass davon ausgegangen wird, dass der Dateiname keine Leerzeichen enthält. Wenn das ein Problem ist, verwenden Sie die --format Option, um die Ausgabe so zu ändern, dass sie den Dateinamen nicht enthält:

inotifywait -q -m -e close_write --format %e myfile.py |
while read events; do
  ./myfile.py
done

In jedem Fall gibt es eine Einschränkung:wenn irgendein Programm myfile.py ersetzt mit einer anderen Datei, anstatt in den bestehenden myfile zu schreiben , inotifywait wird sterben. Viele Redakteure arbeiten so.

Um diese Einschränkung zu umgehen, verwenden Sie inotifywait im Verzeichnis:

inotifywait -e close_write,moved_to,create -m . |
while read -r directory events filename; do
  if [ "$filename" = "myfile.py" ]; then
    ./myfile.py
  fi
done

Verwenden Sie alternativ ein anderes Tool, das dieselbe zugrunde liegende Funktionalität verwendet, wie z /P>

Eingabe (http://entrproject.org/) bietet eine benutzerfreundlichere Schnittstelle zu inotify (und unterstützt auch *BSD &Mac OS X).

Es macht es sehr einfach, mehrere Dateien zum Ansehen anzugeben (nur begrenzt durch ulimit -n ), erleichtert den Umgang mit zu ersetzenden Dateien und erfordert weniger Bash-Syntax:

$ find . -name '*.py' | entr ./myfile.py

Ich habe es in meinem gesamten Projektquellbaum verwendet, um die Komponententests für den Code auszuführen, den ich gerade ändere, und es hat meinen Arbeitsablauf bereits enorm verbessert.

Flags wie -c (Bildschirm zwischen den Läufen löschen) und -d (beenden, wenn eine neue Datei zu einem überwachten Verzeichnis hinzugefügt wird) Fügen Sie noch mehr Flexibilität hinzu, zum Beispiel können Sie Folgendes tun:

$ while sleep 1 ; do find . -name '*.py' | entr -d ./myfile.py ; done

Anfang 2018 befindet es sich noch in der aktiven Entwicklung und ist in Debian &Ubuntu (apt install entr ); Das Bauen aus dem Repo des Autors war auf jeden Fall schmerzfrei.


Ich habe ein Python-Programm mit dem Namen when-changed geschrieben, um genau das zu tun.

Die Verwendung ist einfach:

when-changed FILE COMMAND...

Oder um mehrere Dateien anzusehen:

when-changed FILE [FILE ...] -c COMMAND

FILE kann ein Verzeichnis sein. Rekursiv ansehen mit -r . Verwenden Sie %f um den Dateinamen an den Befehl zu übergeben.


Linux
  1. Wie kann man eine Teilmenge einer Datei zufällig abtasten?

  2. Einen Befehl ausführen, wo eine Datei gefunden wird?

  3. Wie kann ich überprüfen, ob eine Datei vorhanden ist, und einen Befehl ausführen, wenn dies nicht der Fall ist?

  4. Wie hängt man die Ausgabe an eine Datei an?

  5. So generieren Sie eine Teilprüfsumme einer Datei

So verwenden Sie einen Dateibefehl unter Linux

So öffnen Sie eine Datei unter Linux

So mischen Sie Zeilen in einer Datei unter Linux

Wie führe ich einen Befehl in einem Shell-Skript aus?

So verwenden Sie den Befehl lsof unter Linux

So verwenden Sie den Linux-Befehl shred