ada*_*667 17 vim rsync files inotify
我有一个简单的脚本,用于监视文件的更改并将其与远程复制同步:
#!/bin/bash
while inotifywait -e close_write somefile
do
rsync somefile user@host.domain:./somefile
done
Run Code Online (Sandbox Code Playgroud)
它在 nano 上工作得很好,但在 vim 上失败了。当我使用 nano 时,它输出:
somefile CLOSE_WRITE,CLOSE
Run Code Online (Sandbox Code Playgroud)
并开始下一个循环,等待另一个版本。
当我使用 vim 时,没有输出,脚本只是以退出代码 0 关闭。
我做了一些研究,发现 close_write 是使用 initofywait 和 vim 的正确参数(首先我想使用修改事件),但由于某种原因它对我来说失败了。
Gil*_*il' 18
编辑器可以遵循多种策略来保存文件。两个主要变体是覆盖现有文件,或写入新文件并将其移动到位。写入新文件并将其移动到位具有一个很好的特性,即在任何时间点,从文件中读取都会为您提供文件的完整版本(一瞬间是旧的,下一瞬间是新的)。如果文件被原地覆盖,则在一段时间内它是不完整的,如果其他程序刚刚访问它或系统崩溃,这将是有问题的。
Nano 显然会覆盖现有文件。您的脚本会检测完成写入(close_write
事件)的rsync
时间点并在该时间点运行。请注意,如果在 rsync 从第一次保存完成其工作之前快速连续保存两次,则 rsync 可能会获取文件的不完整版本。
另一方面,Vim 使用先写后移动的策略——
echo 'new content' >somefile.new
mv -f somefile.new somefile
Run Code Online (Sandbox Code Playgroud)
旧版本的文件会在新版本移动到位时被删除。此时,inotifywait
命令返回,因为它被告知要监视的文件不再存在。(新somefile
的文件是同名的不同文件。)如果 Vim 被配置为制作备份文件,将会发生类似于
echo 'new content' >somefile.new
ln somefile somefile.old
mv -f somefile.new somefile
Run Code Online (Sandbox Code Playgroud)
而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
Run Code Online (Sandbox Code Playgroud)