You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用find命令的Makefile报错:paths must precede expression

问题:Makefile中find命令报错“paths must precede expression”

我编写了如下Makefile,用来查找所有以"slides"为前缀的.tex文件并编译成PDF:

TSLIDES = $(shell find . -maxdepth 1 -iname 'slides*.tex' -printf '%f
')
TPDFS = $(TSLIDES:%.tex=%.pdf)

all: $(TPDFS)

$(TPDFS): %.pdf: %.tex
    latexmk -pdf $<

但持续收到错误信息(之前能正常运行,现在突然报错):

/usr/bin/find: paths must precede expression: `slides01-intro.tex'
/usr/bin/find: possible unquoted pattern after predicate `-iname'?

我查了find的手册,里面提到这类错误通常是通配符被shell展开导致的,需要用引号或转义包裹,但我已经用单引号了,问题依然存在。尝试去掉-printf参数后还是报同样的错。补充:我使用Windows系统,用的是Git Bash(基于mingw-64)。


解决方法

原因分析

在Windows的Git Bash环境下,Make处理$(shell)时会先移除单引号,导致slides*.tex被Bash直接展开成当前目录下所有匹配的文件名。此时find命令收到的参数变成了find . -maxdepth 1 -iname slides01-intro.tex slides02-xxx.tex ...,find会把后面的文件名当成路径参数,从而触发“paths must precede expression”错误。

可行方案

  1. 用双引号包裹通配符
    双引号会被Make保留并传递给Bash,能有效阻止通配符展开:

    TSLIDES = $(shell find . -maxdepth 1 -iname "slides*.tex" -printf '%f\n')
    
  2. 转义通配符
    用反斜杠转义星号,避免Bash展开:

    TSLIDES = $(shell find . -maxdepth 1 -iname slides\*.tex -printf '%f\n')
    
  3. 改用Make内置的通配符功能(推荐)
    直接用Make的wildcard函数替代find,更简洁且跨环境兼容性更好:

    TSLIDES = $(wildcard slides*.tex)
    TPDFS = $(TSLIDES:%.tex=%.pdf)
    
    all: $(TPDFS)
    
    %.pdf: %.tex
        latexmk -pdf $<
    

内容的提问来源于stack exchange,提问作者Giuseppe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 22:50:42