У меня есть простой скрипт, который контролирует файл на предмет изменений и rsyncs его с удаленным копированием:
#!/bin/bash
while inotifywait -e close_write somefile
do
rsync somefile user@host.domain:./somefile
done
Он работает нормально с nano, но не работает с vim. Когда я использую нано, он выводит:
somefile CLOSE_WRITE,CLOSE
и начинает следующий цикл в ожидании другого издания.
Когда я использую vim, выходных данных нет, скрипт просто закрывается с кодом выхода 0.
Я провел некоторое исследование и выяснил, что close_write - это правильный параметр для использования initofywait вместе с vim (сначала я хотел использовать событие modify), но по какой-то причине он мне не удался.
backupcopy
опция отключена.Ответы:
Редакторы могут использовать несколько стратегий для сохранения файла. Два основных варианта - перезаписать существующий файл или записать в новый файл и переместить его на место. Запись в новый файл и перемещение его на место имеет замечательное свойство, заключающееся в том, что в любой момент времени чтение из файла дает вам полную версию файла (один момент - старый, следующий - новый). Если файл перезаписан на месте, есть время, в течение которого он является неполным, что является проблематичным, если какая-то другая программа обращается к нему только тогда или если происходит сбой системы.
Нано явно перезаписывает существующий файл. Ваш скрипт обнаруживает точку, когда он закончил писать (
close_write
событие), и запускаетсяrsync
в этой точке. Обратите внимание, что rsync может получить неполную версию файла, если дважды сохранить его в быстрой последовательности, прежде чем rsync завершит свою работу с первого сохранения.Vim, с другой стороны, использует стратегию записи-затем-перемещения - что-то вроде эффекта
Что происходит со старой версией файла, так это то, что он удаляется в тот момент, когда новая версия перемещается на место. В этот момент
inotifywait
команда возвращается, потому что файл, который ей сказали смотреть, больше не существует. (Новыйsomefile
- это другой файл с тем же именем.) Если Vim был настроен для создания файла резервной копии, что-то произойдет,и
inotifywait
теперь будет смотреть резервное копирование.Для получения дополнительной информации о стратегиях сохранения файлов см. Как можно сделать живое обновление во время работы программы? и файл разрешений и сохранения
Vim можно сказать использовать стратегию перезаписи: отключите
backupcopy
опцию (:set nobackupcopy
). Это рискованно, как указано выше.Чтобы справиться с обеими стратегиями сохранения, просмотрите каталог и отфильтруйте их
close_write
иmoved_to
событияsomefile
.источник
:wa
. Затем моя сборка запускается один раз для каждого записанного файла.:wa
, вы получаете последовательные события inotify. Вам нужно подождать после первого, чтобы увидеть, придут ли другие. Но вы можете использовать код, представленный здесь: дополнительная сложность будет идти внутри…
.while true; do inotifywait ... [no -m]; make; sleep .1; done;
или около того. Есть некоторые ошибки, но я пришел к чему-то вполне подходящему.