使用entr命令运行多条命令自动编译Groff文档的正确方法
原写法问题说明
- 仅触发一次的写法问题:你将
refer命令作为entr的执行参数,后续的groff放在了entr的外层管道中,只有第一次entr启动时的refer输出会被groff处理,后续entr触发的refer输出不会被外层管道捕获,因此看起来只执行了一次编译。 - 死循环写法问题:冗余的
while true循环+手动杀父进程的逻辑破坏了entr本身的信号处理机制,导致Ctrl+C发送的SIGINT信号无法被正常识别,进程无法退出陷入死循环。
正确实现方案
方案1:单行命令版
直接将完整编译逻辑放入entr的执行参数中,同时监控源文件和参考文献库:
{ echo 输入文件.ms; echo references.bib; } | entr -s 'refer references.bib 输入文件.ms | groff -ms 输入文件.ms -T pdf > 输出文件.pdf'
如果需要参数化调用,可直接使用如下格式:
{ echo "$1"; echo references.bib; } | entr -s 'refer references.bib '"$1"' | groff -ms '"$1"' -T pdf > '"$2"
方案2:脚本封装版(更易用)
保存为groff-autobuild.sh,执行chmod +x groff-autobuild.sh赋予执行权限后,用./groff-autobuild.sh 输入文件.ms 输出文件.pdf运行即可:
#!/bin/sh if [ $# -ne 2 ]; then echo "用法: $0 <输入.ms文件> <输出.pdf路径>" exit 1 fi IN_FILE="$1" OUT_FILE="$2" BIB_FILE="references.bib" compile() { refer "$BIB_FILE" "$IN_FILE" | groff -ms "$IN_FILE" -T pdf > "$OUT_FILE" echo "[$(date +%H:%M:%S)] 编译完成,输出路径:$OUT_FILE" } # 启动时先执行一次编译 compile # 监控输入文件、参考文献库变更自动触发编译 { echo "$IN_FILE"; echo "$BIB_FILE"; } | entr -p compile
实现特性
- 支持
Ctrl+C正常终止进程,无死循环问题 - 源文件、参考文献库修改都会自动触发编译
- 启动时自动执行一次编译,无需手动修改文件触发
- 每次编译完成会打印时间戳提示
内容的提问来源于stack exchange,提问作者Eidolon
相关产品推荐
相关产品推荐

