Tengo un script simple que monitorea los cambios en el archivo y lo sincroniza con una copia remota:
#!/bin/bash
while inotifywait -e close_write somefile
do
rsync somefile [email protected]:./somefile
done
Funciona bien con nano, pero falla con vim. Cuando uso nano, genera:
somefile CLOSE_WRITE,CLOSE
y comienza el siguiente ciclo esperando otra edición.
Cuando uso vim, no hay salida, el script solo se cierra con el código de salida 0.
Investigué un poco y descubrí que close_write es el parámetro correcto para usar initofywait junto con vim (primero quería usar el evento de modificación), pero por alguna razón falla para mí.
backupcopy
opción está desactivada.Respuestas:
Los editores pueden seguir varias estrategias para guardar un archivo. Las dos variantes principales son sobrescribir el archivo existente o escribir en un archivo nuevo y moverlo en su lugar. Escribir en un archivo nuevo y moverlo en su lugar tiene la buena propiedad de que, en cualquier momento, la lectura del archivo le brinda una versión completa del archivo (un instante el anterior, el siguiente al nuevo). Si el archivo se sobrescribe en su lugar, hay un tiempo durante el cual está incompleto, lo cual es problemático si algún otro programa accede a él en ese momento o si el sistema falla.
Nano aparentemente sobrescribe el archivo existente. Su script detecta el punto cuando termina de escribir (el
close_write
evento) y se ejecutarsync
en ese punto. Tenga en cuenta que es posible que rsync obtenga una versión incompleta del archivo, si guarda dos veces seguidas, antes de que rsync haya completado su trabajo desde el primer guardado.Vim, por otro lado, utiliza la estrategia de escribir y luego mover, algo en el sentido de
Lo que sucede con la versión anterior del archivo es que se elimina en el punto donde la nueva versión se coloca en su lugar. En este punto, el
inotifywait
comando regresa porque el archivo que se le ha dicho que vigile ya no existe. (El nuevosomefile
es un archivo diferente con el mismo nombre). Si Vim se hubiera configurado para hacer un archivo de copia de seguridad, lo que sucedería es algo comoy
inotifywait
ahora estaría mirando la copia de seguridad.Para obtener más información sobre las estrategias de guardado de archivos, consulte ¿Cómo es posible hacer una actualización en vivo mientras se ejecuta un programa? y permisos de archivo y guardar
Se le puede decir a Vim que use la estrategia de sobrescritura: desactive la
backupcopy
opción (:set nobackupcopy
). Esto es arriesgado, como se indicó anteriormente.Para manejar ambas estrategias de guardado, mire el directorio y filtre los eventos
close_write
y losmoved_to
eventossomefile
.fuente
:wa
. Luego, mi compilación se ejecuta una vez por cada archivo escrito.:wa
, obtendrá sucesivos eventos de inotify. Tendría que esperar después del primero para ver si vienen otros. Pero puede usar el código presentado aquí: la complejidad adicional iría dentro del…
.while true; do inotifywait ... [no -m]; make; sleep .1; done;
o menos. Hay algunas trampas, pero he llegado a algo bastante viable.