Редакторы могут использовать несколько стратегий для сохранения файла. Два основных варианта - перезаписать существующий файл или записать в новый файл и переместить его на место. Запись в новый файл и перемещение его на место имеет замечательное свойство, заключающееся в том, что в любой момент времени чтение из файла дает вам полную версию файла (один момент - старый, следующий - новый). Если файл перезаписан на месте, есть время, в течение которого он является неполным, что является проблематичным, если какая-то другая программа обращается к нему только тогда или если происходит сбой системы.
Нано явно перезаписывает существующий файл. Ваш скрипт обнаруживает точку, когда он закончил писать ( close_write
событие), и запускается rsync
в этой точке. Обратите внимание, что rsync может получить неполную версию файла, если дважды сохранить его в быстрой последовательности, прежде чем rsync завершит свою работу с первого сохранения.
Vim, с другой стороны, использует стратегию записи-затем-перемещения - что-то вроде эффекта
echo 'new content' >somefile.new
mv -f somefile.new somefile
Что происходит со старой версией файла, так это то, что он удаляется в тот момент, когда новая версия перемещается на место. В этот момент inotifywait
команда возвращается, потому что файл, который ей сказали смотреть, больше не существует. (Новый somefile
- это другой файл с тем же именем.) Если Vim был настроен для создания файла резервной копии, что-то произойдет,
echo 'new content' >somefile.new
ln somefile somefile.old
mv -f somefile.new somefile
и inotifywait
теперь будет смотреть резервное копирование.
Для получения дополнительной информации о стратегиях сохранения файлов см. Как можно сделать живое обновление во время работы программы? и файл разрешений и сохранения
Vim можно сказать использовать стратегию перезаписи: отключите backupcopy
опцию ( :set nobackupcopy
). Это рискованно, как указано выше.
Чтобы справиться с обеими стратегиями сохранения, просмотрите каталог и отфильтруйте их close_write
и moved_to
события somefile
.
inotifywait -m -e close_write,moved_to --format %e/%f . |
while IFS=/ read -r events file; do
if [ "$file" = "somefile" ]; then
…
fi
done