我的制作文件:
all: ...(other rules) clean
clean:
rm $(find . -type f -executable)
当我从上面的 Makefile 中删除clean
规则时,一切都按预期工作。添加后,make
(也make clean
)命令导致:
rm
rm: missing operand
Try 'rm --help' for more information.
make: *** [Makefile:46: clean] Error 1
是什么导致这里出现问题,我该如何解决?
有几个问题。
将 Makefile 中的 $ 符号传递给 shell
你想运行命令
让 shell 进行命令替换。为此,您需要编写
美元翻了一番,因为 Make 本身使用
$
.处理没有什么可“清理”的案子
如果 的输出
find
为空,则在命令替换之后变成
并且典型的
rm
命令抱怨你没有告诉它要删除什么。解决此问题的一种方法是xargs
使用find
. 它接受 rm 的输出,find
如果有的话,它会将其分成块并运行 rm。处理文件名中的任意字符
Unix 文件名由
/
字符分隔的组件组成。组件本身可以是除/
NUL 之外的任何字符序列。特别是一个组件可以包括换行符、空格、制表符、*
.对于命令替换 case (
rm $(find . -type f -executable)
) 情况,shell 将处理 find 的输出。所以空白字符会导致分词,*
字符会导致文件名“globbing”发生等。为了合理的实现,xargs
避免这种情况。如果文件名以 then 开头,
-
则rm
可能会将它们视为命令的选项。避免这种情况的简单方法是--
在命令中添加以指示“选项结束”。剩下的主要问题是换行符。
xargs
在换行符上拆分输入,所以如果你有一个文件调用abc\ndef
thenfind
将输出并将
xargs
使用rm
2 个文件名abc
和def
.要解决此问题,请告诉两者
find
并xargs
使用不能出现在文件名中的 1 字符 (NUL) 作为分隔符而不是换行符。最好的解决方案,如果你
find
支持它在这里,您可以找到直接删除文件(如果有)。它更有效,因为它不需要启动额外的进程。没有 shell 或 xargs 进程需要转义字符。没有要处理的特殊字符
make
。正确处理“没有要删除的文件”的情况。