Редактори можуть дотримуватися декількох стратегій для збереження файлу. Два основні варіанти - це перезаписати існуючий файл або записати в новий файл і перемістити його на місце. Запис у новий файл і переміщення його на місці має приємне властивість, що в будь-який момент часу читання з файлу дає вам повну версію файлу (один миттєвий старий, наступний миттєвий новий). Якщо файл перезаписаний на місці, є час, протягом якого він є неповним, що проблематично, якщо якась інша програма отримує доступ до нього саме тоді або якщо система виходить з ладу.
Нано, мабуть, перезаписує існуючий файл. Ваш сценарій визначає точку, коли він закінчується написанням ( 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