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écute rsync
à 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
echo 'new content' >somefile.new
mv -f somefile.new somefile
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 nouveau somefile
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 comme
echo 'new content' >somefile.new
ln somefile somefile.old
mv -f somefile.new somefile
et 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 les moved_to
événements pour somefile
.
inotifywait -m -e close_write,moved_to --format %e/%f . |
while IFS=/ read -r events file; do
if [ "$file" = "somefile" ]; then
…
fi
done