希望这将有助于澄清一些事情:
Watchman 作为每用户服务运行以监控您的文件系统。它可以:
- 在文件更改发生时提供实时订阅
- 发生文件更改时触发在后台运行的命令
- 回答有关文件自给定时间点以来如何更改的查询
pywatchman 是一个 python 客户端实现,允许您构建使用来自 watchman 的信息的应用程序。 watchman-make 和 watchman-wait 工具是使用 pywatchman 实现的。
watchman-make 是一个工具,可帮助您在文件更改时调用make(或类似程序)。在您要运行的程序不需要刚刚更改的文件的特定列表的情况下,这是最合适的。 make 属于此类别; make 将分析您的 Makefile 中的依赖关系,然后仅构建更改的部分。您也可以执行 python distutils 或 setuptools setup.py 脚本。
本机守望者触发器比watchman-make 更难使用,因为它们是由守望者服务在后台生成的,并通过更改文件列表传递。这些最适合完全无人参与的进程,您不需要查看输出并且需要更改文件的精确列表。
根据您的描述,听起来最简单的解决方案是执行编译步骤然后执行同步的脚本,类似于以下内容;我们就叫它build-and-sync.sh
#!/bin/sh
python -m compileall .
rsync -avz . host:/path/
(如果您真的不需要.pyc 文件而只需要同步,那么您可以简单地从上面的脚本中删除python 行并让它运行rsync)
然后您可以在事情发生变化时使用watchman-make 执行此操作:
watchman-make --make='build-and-sync.sh' -p '**/*.py' -t dummy
然后,在更改任何.py 文件(或一组.py 文件)后,watchman-make 将执行build-and-sync.sh dummy。这应该足够了,除非您有足够多的 python 文件,以至于每次进行更改时编译步骤都需要很长时间。 watchman-make 将继续运行,直到您按 CTRL-C 或以其他方式终止进程;它会在终端窗口的前台运行,除非您使用 nohup、tmux 或 screen 之类的东西来让它保持更长时间。
如果是这种情况,那么您可以尝试使用 make 和模式规则来仅编译更改的 python 文件,或者如果使用 make 表达起来很尴尬,那么也许值得使用 pywatchman 来建立一个订阅并编译更改的文件。这是一个更高级的用例,我建议查看watchman-wait 的代码以了解如何实现。除非您有大量文件或同步时间非常紧迫,否则可能不值得为此付出额外的努力。
我建议先尝试最简单的解决方案,看看是否满足您的需求,然后再尝试更复杂的选项之一。
使用原生触发器
作为替代方案,您可以使用触发器。它们在后台运行,其输出将发送到 watchman 日志文件。与使用 watchman-make 相比,它们更难使用。
您需要编写一个小程序,通常是一个脚本,来接收来自触发器的更改文件列表;最好的方法是通过脚本的标准输入。您可以接收每行一个文件的列表或具有更多结构化信息的 JSON 对象。我们称这个脚本为trigger-build-and-sync;由您来实现脚本的内容。假设您只需要 stdin 上的文件列表。
此命令将设置触发器;你调用它一次,它会一直持续到手表被移除:
watchman -j <<-EOT
["trigger", "/path/to/root", {
"name": "build-and-sync",
"expression": ["suffix", "py"],
"command": "/path/to/trigger-build-and-sync",
"append_files": false,
"stdin": "NAME_PER_LINE"
}]
EOT
完整的文档可以在https://facebook.github.io/watchman/docs/cmd/trigger.html#extended-syntax找到