627 votes

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

Je veux un moyen simple et rapide d'exécuter une commande à chaque fois qu'un fichier est modifié. Je veux quelque chose de très simple, quelque chose que je laisserai tourner sur un terminal et que je fermerai dès que j'aurai fini de travailler sur ce fichier.

Actuellement, j'utilise ceci :

while read; do ./myfile.py ; done

Et ensuite je dois aller dans ce terminal et appuyer sur Enter chaque fois que j'enregistre ce fichier sur mon éditeur. Ce que je veux, c'est quelque chose comme ça :

while sleep_until_file_has_changed myfile.py ; do ./myfile.py ; done

Ou toute autre solution aussi simple que cela.

BTW : J'utilise Vim, et je sais que je peux ajouter une autocommande pour exécuter quelque chose sur BufWrite, mais ce n'est pas le genre de solution que je veux maintenant.

Mise à jour : Je veux quelque chose de simple, jetable si possible. De plus, je veux quelque chose qui s'exécute dans un terminal car je veux voir la sortie du programme (je veux voir les messages d'erreur).

A propos des réponses : Merci pour toutes vos réponses ! Elles sont toutes très bonnes, et chacune adopte une approche très différente des autres. Comme je ne dois en accepter qu'une seule, j'accepte celle que j'ai effectivement utilisée (elle était simple, rapide et facile à mémoriser), même si je sais qu'elle n'est pas la plus élégante.

0 votes

Possibilité de duplication de site croisé de : stackoverflow.com/questions/2972765/ ( bien qu'ici c'est le sujet =) )

0 votes

J'ai déjà référencé un duplicate cross site et il a été refusé :S ;)

4 votes

La solution de Jonathan Hartley s'appuie sur d'autres solutions proposées ici et corrige les gros problèmes des réponses les plus votées : absence de certaines modifications et inefficacité. Veuillez changer la réponse acceptée par la sienne, qui est également maintenue sur github à l'adresse suivante github.com/tartley/rerun2 (ou à une autre solution sans ces défauts)

11voto

Florian Diesch Points 3700

Jetez un coup d'œil à incron . Il est similaire à cron, mais utilise les événements inotify au lieu du temps.

0 votes

Cela peut fonctionner, mais la création d'une entrée incron est un processus assez laborieux comparé aux autres solutions de cette page.

8voto

Atika Points 199

Une autre solution avec NodeJs, fsmonitor :

  1. Installer

    sudo npm install -g fsmonitor
  2. Depuis la ligne de commande (exemple, surveiller les journaux et "vendre au détail" si un fichier journal change)

    fsmonitor -s -p '+*.log' sh -c "clear; tail -q *.log"

0 votes

Note complémentaire : l'exemple pourrait être résolu par tail -F -q *.log Je pense.

0 votes

C'était juste pour donner un exemple, tail -f n'a pas clear le terminal.

7voto

ctgPi Points 179

Si votre programme génère une sorte de journal/sortie, vous pouvez créer un Makefile avec une règle pour ce journal/sortie qui dépend de votre script et faire quelque chose comme

while true; do make -s my_target; sleep 1; done

Alternativement, vous pouvez créer une cible fictive et faire en sorte que la règle la concernant appelle votre script et touche la cible fictive (tout en dépendant toujours de votre script).

11 votes

while sleep 1 ; do something ; done est légèrement meilleur que while true ; do something ; sleep 1 ; done . Au moins, il s'arrête facilement en appuyant sur Ctrl+C.

0 votes

La suppression de la mise en veille va-t-elle provoquer une boucle d'occupation (le processeur génère de la chaleur et nuit à l'autonomie de la batterie d'un ordinateur portable) ?

3 votes

@StevenLu : non, le sleep n'est pas une attente occupée. Le problème est que si le sommeil est dans le corps, Control-C va tuer le sommeil et la boucle va recommencer. La consommation d'énergie liée au redémarrage de la boucle est insignifiante. Essayez-le vous-même dans un terminal. Vous devez maintenir Control-C enfoncé pour que cela fonctionne, si vous avez du sleep dans le corps.

7voto

Eric Leschinski Points 6388

Sous Linux :

man watch

watch -n 2 your_command_to_run

Exécute la commande toutes les 2 secondes.

Si l'exécution de votre commande prend plus de 2 secondes, watch attendra qu'elle soit terminée avant de la recommencer.

0 votes

C'est assez simple, bien que ce soit un peu du gaspillage, c'est facile pour les tâches de développement comme les modifications en direct des styles.

2 votes

Que se passe-t-il lorsque l'exécution de la commande prend plus de deux secondes ?

0 votes

@thirtythreeforty Une expérience rapide sur Ubuntu montre que watch attendra les deux secondes complètes, quelle que soit la durée d'exécution de la commande. Pour info, la période de sommeil peut être spécifiée avec '-n', jusqu'à un minimum de 0,1 seconde.

7voto

Wouter van Vliet Points 171

Regardez dans Guard, en particulier avec ce plugin :

https://github.com/hawx/guard-Shell

Vous pouvez le configurer pour surveiller un nombre quelconque de modèles dans le répertoire de votre projet, et exécuter des commandes lorsque des changements se produisent. Il y a même de fortes chances qu'il existe un plugin disponible pour ce que vous essayez de faire en premier lieu.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X