J'ai un script simple qui surveille les modifications du fichier et le synchronise avec une copie à distance:
#!/bin/bash
while inotifywait -e close_write somefile
do
rsync somefile [email protected]:./somefile
done
Cela fonctionne très bien avec nano, mais échoue avec vim. Lorsque j'utilise nano, il génère:
somefile CLOSE_WRITE,CLOSE
et démarre la boucle suivante en attendant une autre édition.
Lorsque j'utilise vim, il n'y a pas de sortie, le script se ferme simplement avec le code de sortie 0.
J'ai fait quelques recherches et j'ai découvert que close_write est le bon paramètre pour utiliser initofywait avec vim (d'abord, je voulais utiliser l'événement de modification), mais pour une raison quelconque, cela échoue pour moi.
backupcopy
option est désactivée.Réponses:
Les éditeurs peuvent suivre plusieurs stratégies pour enregistrer un fichier. Les deux variantes principales consistent à écraser le fichier existant ou à écrire dans un nouveau fichier et à le déplacer en place. Écrire dans un nouveau fichier et le déplacer en place a la belle propriété qu'à tout moment, la lecture du fichier vous donne une version complète du fichier (un instant l'ancien, l'instant suivant le nouveau). Si le fichier est écrasé sur place, il y a un temps pendant lequel il est incomplet, ce qui est problématique si un autre programme y accède à ce moment ou si le système plante.
Nano écrase apparemment le fichier existant. Votre script détecte le moment où il a fini d'écrire (l'
close_write
événement) et s'exécutersync
à ce stade. Notez qu'il est possible pour rsync de récupérer une version incomplète du fichier, si vous enregistrez deux fois de suite rapidement, avant que rsync n'ait terminé son travail à partir de la première sauvegarde.Vim, d'autre part, utilise la stratégie d'écriture puis de déplacement - quelque chose qui a pour effet de
Ce qui arrive à l'ancienne version du fichier, c'est qu'il est supprimé au point où la nouvelle version est déplacée en place. À ce stade, la
inotifywait
commande revient, car le fichier qu'il a été invité à surveiller n'existe plus. (Le nouveausomefile
est un fichier différent portant le même nom.) Si Vim avait été configuré pour créer un fichier de sauvegarde, ce qui se passerait serait quelque chose commeet
inotifywait
serait maintenant en train de regarder la sauvegarde.Pour plus d'informations sur les stratégies d'enregistrement de fichiers, voir Comment est-il possible de faire une mise à jour en direct pendant l'exécution d'un programme? et autorisations de fichiers et enregistrement
On peut dire à Vim d'utiliser la stratégie de remplacement: désactivez l'
backupcopy
option (:set nobackupcopy
). C'est risqué, comme indiqué ci-dessus.Pour gérer les deux stratégies de sauvegarde, regardez le répertoire et filtrez les deux
close_write
et lesmoved_to
événements poursomefile
.la source
:wa
. Ensuite, ma build est exécutée une fois pour chaque fichier écrit.:wa
, vous obtenez des événements inotify successifs. Vous devrez attendre après le premier pour voir si d'autres arrivent. Mais vous pouvez utiliser le code présenté ici: la complexité supplémentaire irait à l'intérieur du…
.while true; do inotifywait ... [no -m]; make; sleep .1; done;
ou non. Il y a quelques pièges, mais je suis arrivé à quelque chose de tout à fait réalisable.