我有一个简单的脚本,可以监视文件的更改并将其与远程复制同步:
#!/bin/bash
while inotifywait -e close_write somefile
do
rsync somefile [email protected]:./somefile
done
它在 nano 上工作得很好,但在 vim 上却失败了。当我使用 nano 时,它输出:
somefile CLOSE_WRITE,CLOSE
并开始下一个循环等待另一个版本。
当我使用 vim 时,没有输出,脚本只是以退出代码 0 关闭。
我做了一些研究,发现 close_write 是使用 initofywait 和 vim 的正确参数(首先我想使用修改事件),但由于某种原因它对我来说失败了。
答案1
编辑者可以遵循多种策略来保存文件。两个主要变体是覆盖现有文件,或写入新文件并将其移动到位。写入新文件并将其移动到位具有一个很好的特性,即在任何时间点从文件中读取都会为您提供文件的完整版本(前一瞬间是旧文件,下一瞬间是新文件)。如果文件被就地覆盖,则有一段时间它是不完整的,如果此时有其他程序访问它或者系统崩溃,就会出现问题。
Nano 显然会覆盖现有文件。您的脚本会检测完成写入的时间点(事件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