GNU/Linux >> Tutoriels Linux >  >> Linux

Comment exécuter une commande à chaque fois qu'un fichier change ?

Simple, en utilisant inotifywait (installez le inotify-tools de votre distribution paquet):

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

ou

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

Le premier extrait est plus simple, mais il présente un inconvénient important :il manquera les modifications effectuées alors que inotifywait n'est pas en cours d'exécution (en particulier lorsque myfile est en cours d'exécution). Le deuxième extrait n'a pas ce défaut. Cependant, méfiez-vous qu'il suppose que le nom du fichier ne contient pas d'espace. Si c'est un problème, utilisez le --format option pour modifier la sortie afin de ne pas inclure le nom du fichier :

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

Dans tous les cas, il y a une limitation :si un programme remplace myfile.py avec un fichier différent, plutôt que d'écrire dans le myfile existant , inotifywait mourront. De nombreux éditeurs fonctionnent de cette façon.

Pour contourner cette limitation, utilisez inotifywait sur le répertoire :

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

Vous pouvez également utiliser un autre outil qui utilise la même fonctionnalité sous-jacente, comme incron (vous permet d'enregistrer des événements lorsqu'un fichier est modifié) ou fswatch (un outil qui fonctionne également sur de nombreuses autres variantes d'Unix, en utilisant l'analogue de chaque variante de l'inotify de Linux). /P>

entrée (http://entrproject.org/) fournit une interface plus conviviale pour inotify (et prend également en charge *BSD et Mac OS X).

Il est très facile de spécifier plusieurs fichiers à surveiller (limité uniquement par ulimit -n ), simplifie le traitement des fichiers à remplacer et nécessite moins de syntaxe bash :

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

Je l'utilise sur l'ensemble de l'arborescence des sources de mon projet pour exécuter les tests unitaires du code que je modifie actuellement, et cela a déjà énormément amélioré mon flux de travail.

Indicateurs comme -c (effacer l'écran entre les exécutions) et -d (quittez lorsqu'un nouveau fichier est ajouté à un répertoire surveillé) ajoutez encore plus de flexibilité, par exemple vous pouvez faire :

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

Début 2018, il est toujours en développement actif et peut être trouvé dans Debian et Ubuntu (apt install entr ); la construction à partir du dépôt de l'auteur s'est faite sans douleur dans tous les cas.


J'ai écrit un programme Python pour faire exactement cela appelé when-changed.

L'utilisation est simple :

when-changed FILE COMMAND...

Ou pour regarder plusieurs fichiers :

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

FILE peut être un répertoire. Regarder récursivement avec -r . Utilisez %f pour passer le nom du fichier à la commande.


Linux
  1. Comment enregistrer la sortie de la commande dans un fichier sous Linux

  2. Comment puis-je vérifier qu'un fichier existe et exécuter une commande sinon?

  3. Comment exécuter un fichier python sous Linux

  4. Comment éditer un fichier texte dans mon terminal

  5. Commande Shell pour surveiller les changements dans un fichier

Comment utiliser une commande de fichier sous Linux

Comment ouvrir un fichier sous Linux

Comment mélanger les lignes dans un fichier sous Linux

Comment exécuter une commande dans un script shell ?

Comment utiliser la commande lsof sous Linux

Comment utiliser la commande shred Linux