如何防止在 Texmaker 更改時使用 fswatch 自動編譯循環?
在檢查了這個問題和未接受的答案後,我嘗試對其進行測試。首先,我使用以下命令測試了推薦的命令:
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
到零更改?- TexMaker 是否可以選擇
report.tex
在保存時將更改量從 2 減少到 1ctrl+s
?
fswatch
根據不同的作業系統使用不同的後端。讓我們假設整體行為是相同的。
fswatch
在我的 Linux 系統上,使用(和 option )的嘗試-x
給出PlatformSpecific
的事件無助於區分讀取事件、寫入事件、打開事件和關閉事件以及許多其他可能的事件(請注意,Linux 的inotify甚至可以區分兩種類型的關閉事件,一種在沒有變化之後,一種在變化之後,這將有助於進一步)。這也是您獲得多個事件的原因。從原始碼讀取將觸發編譯嘗試,其中將再次讀取此原始碼。循環創建。
這就是你所有問題的原因。您應該僅在寫入事件時觸發,並且僅在文件停止寫入時觸發,但
fswatch
將所有這些事件都視為PlatformSpecific。您需要(a)可以區分事件的工具,或者進行定期民意調查以比較日期或內容(我相信最後一部分是從 OP 的連結中接受的答案)。您可以
fswatch
在--one-event
不xargs
與 OP 連結的已接受答案結合的情況下使用模式,因此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 無法在讀取循環中處理這個問題。使用inotify工具而不是inotifywait命令的非 shell 工具遲早會更適合(例如:https ://pypi.org/project/inotify/ )。