将 inotifywait 与 vim 一起使用

将 inotifywait 与 vim 一起使用

我有一个简单的脚本,可以监视文件的更改并将其与远程复制同步:

#!/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_writemoved_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

相关内容