检查后这个问题和不被接受的答案,我尝试测试它。首先我使用以下命令测试了推荐的命令:
fswatch -o report.tex | xargs -n1 -I{} pdflatex report.tex
这导致了无限的编译循环,我认为这稍微低效,而且,它没有创建足够长的机会窗口来访问 PDF。因此,我尝试使用文件中的 TexMaker 中的命令来调试为什么fswatch
会产生无限编译循环:ctrl+s
report.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.tex
TexMaker 是否可以选择在保存时将更改数量从 2 减少到 1ctrl+s
?
答案1
fswatch
根据不同的操作系统使用不同的后端。我们假设整体行为是相同的。
在我的 Linux 系统上,尝试使用fswatch
(和选项-x
)给出的PlatformSpecific
事件无助于区分读事件,一个写事件,一个打开事件和一个关闭事件以及许多其他可能的事件(请注意,Linux'inotify甚至区分两种类型的关闭事件,一种是在没有更改之后,一种是在更改之后,这将在这里进一步帮助)。这也是您获得多个事件的原因。
从源代码读取将触发编译尝试,这将除其他外再读一遍这个来源。循环已创建。
这就是你所有问题的原因。你应该只触发写事件,并且仅当文件停止写入时,但fswatch
认为所有这些事件都是特定于平台。您需要能够区分事件的工具,或者进行定期民意调查来比较日期或内容(我相信最后一部分是从OP的链接中接受接受的答案)。
您可以在不与OP的链接接受答案相结合的模式fswatch
下使用,这样就不会无限期地再次触发,而是等待完成。当然,这样做时您必须处理竞争条件,以防您错过之间的事件。--one-event
xargs
fswatch
pdftex
结论是:不要试图让一切都适应fswatch
,fswatch
用更合适的工具来改变。
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/)。