如何防止在 Texmaker 中发生更改时使用 fswatch 自动编译循环?

如何防止在 Texmaker 中发生更改时使用 fswatch 自动编译循环?

检查后这个问题和不被接受的答案,我尝试测试它。首先我使用以下命令测试了推荐的命令:

fswatch -o report.tex | xargs -n1 -I{} pdflatex report.tex

这导致了无限的编译循环,我认为这稍微低效,而且,它没有创建足够长的机会窗口来访问 PDF。因此,我尝试使用文件中的 TexMaker 中的命令来调试为什么fswatch会产生无限编译循环:ctrl+sreport.tex

fswatch -o report.tex | xargs -n1 -I{} echo "hello world"
hello world
hello world

在那里,我观察到触发ctrl+s/保存触发report.tex了两个检测到的更改fswatch。此外,我f6在 TexMaker 中的命令以及命令上对其进行了测试,pdflatex report.tex并观察到fswatch两次尝试都检测到了 3 个更改:

fswatch -o report.tex | xargs -n1 -I{} echo "hello world"
hello world
hello world
hello world

后者似乎足以导致无限编译循环。因此,我想问,report.tex当从TexMaker保存更改时,如何确保编译一次?

我认为可能导致有效答案的子问题可能如下所列,但我没有找到令人满意的答案:

  • 例如, fswatch 是否有一个参数来忽略下一个n-miliseconds或下一个的更改n-changes?在我看来,该3.2.3 Numeric Event Flags部分fswatch 文档似乎只允许使用n-th事件标志。然而我还没有成功地实现传递这样的参数来抑制编译。
  • 或者我可以传递给pdflatex报告以将编译时检测到的三个更改减少到report.tex零更改吗?
  • report.texTexMaker 是否可以选择在保存时将更改数量从 2 减少到 1 ctrl+s

答案1

fswatch根据不同的操作系统使用不同的后端。我们假设整体行为是相同的。

在我的 Linux 系统上,尝试使用fswatch(和选项-x)给出的PlatformSpecific事件无助于区分事件,一个事件,一个打开事件和一个关闭事件以及许多其他可能的事件(请注意,Linux'inotify甚至区分两种类型的关闭事件,一种是在没有更改之后,一种是在更改之后,这将在这里进一步帮助)。这也是您获得多个事件的原因。

从源代码读取将触发编译尝试,这将除其他外再读一遍这个来源。循环已创建。

这就是你所有问题的原因。你应该只触发事件,并且仅当文件停止写入时,但fswatch认为所有这些事件都是特定于平台。您需要能够区分事件的工具,或者进行定期民意调查来比较日期或内容(我相信最后一部分是从OP的链接中接受接受的答案)。

您可以在不与OP的链接接受答案相结合的模式fswatch下使用,这样就不会无限期地再次触发,而是等待完成。当然,这样做时您必须处理竞争条件,以防您错过之间的事件。--one-eventxargsfswatchpdftex

结论是:不要试图让一切都适应fswatchfswatch用更合适的工具来改变。


Linux 上的替代方法示例(因为这是与特定操作系统相关的,并且 OP 没有说明我将使用此示例的操作系统)。

inotifywait有正确的选项来监视写入,并且实际上只有写入结束(因此不是 MODIFY 事件,而是只有 CLOSE_WRITE 事件)。当文件实际移动、删除和替换时,可能还有其他事情需要检查和适应,但我并不试图找出所有细节。所以:

inotifywait -m -e CLOSE_WRITE report.tex | xargs -n1 -I{} pdflatex report.tex

将是一个好的开始。

要提供事件循环:

inotifywait -m -r -e CLOSE_WRITE somedir | while read -r dir events filename; do
    if [ "$filename" != "${filename%.tex}" ]; then
        pdflatex "$dir/$filename"
    fi
done

可能是一个好的开始。除了...

唉,当然有一些警告,首先是包含空格或特殊字符的文件名。可以进一步解决它们,例如在输出中--format似乎接受\0(我认为还--csv不够),但是 shell 无法在环形。迟早会出现使用非 shell 工具inotify设施但不是inotify等待命令会更适合(例如:https://pypi.org/project/inotify/)。

相关内容