Makefile - make 找到一个文件而 shell 没有
Makefile - make finds a file whilst shell does not
我写了一段 Makefile,它在执行 rm 之前检查文件是否存在。
clean:
echo "Attempt to remove $(exec) file"
if test -f "${exec}" ; then \
echo "Removing file ${exec}" ; \
rm ${exec} ; \
else \
echo "No ${exec} file to remove" ; \
fi
if "$(wildcard *.o)" = "" ; then \
echo "No files found" ; \
else \
echo " Found $(wildcard *.o) " ; \
fi
第一个 if 语句工作正常
尝试删除 hello 文件
没有要删除的 hello 文件
而第二个产生这个:
/bin/sh: 1: main.o factorial.o: 未找到
找到 main.o factorial.o
我的问题是:为什么 make recipe 会产生有效的输出(这些文件确实存在)而 shell才不是?为什么 shell 甚至试图找到它们?
感谢您花时间阅读这个问题。这是我第一次来这里,所以如果我做错了什么,请告诉我
if main.o
与 if test -f main.o
非常不同。前者尝试 运行 命令 main.o
,而后者 运行 命令 test
。 if "main.o factorial.o"
是相似的,因为它尝试 运行 一个名为 main.o factorial.o
的命令,shell 正确地抱怨它找不到。您的 PATH 中不太可能有一个名为 main.o factorial.o
的文件(这是一个名称中带有 space 的文件)。
但是不要这样做。在取消链接之前检查文件是否存在绝对没有意义。存在固有的竞争条件。只需尝试删除该文件,并处理如果该文件不存在可能发生的错误。
编写 rm $(wildcard *.o)
并让 rm
为不存在的文件发出错误消息要容易得多。或者 rm -f $(wildcard *.o)
来抑制错误。如果你真的坚持遍历文件并检查,你可以这样做:
for f in $(wildcard *.o); do \
if ! test -f "$$f"; then echo "$$f" does not exist; \
else rm "$$f"; fi
但真的不值得。此外,这似乎毫无意义,因为 wildcard
只会扩展到存在的文件。 (但请注意,这表现出相同的竞争条件:通配符可能扩展为文件列表,但在通配符扩展和 rm
为 运行 之间可能会创建新文件。) ' 像这样使用 wildcard
。明确列出您要使用的文件。
我写了一段 Makefile,它在执行 rm 之前检查文件是否存在。
clean:
echo "Attempt to remove $(exec) file"
if test -f "${exec}" ; then \
echo "Removing file ${exec}" ; \
rm ${exec} ; \
else \
echo "No ${exec} file to remove" ; \
fi
if "$(wildcard *.o)" = "" ; then \
echo "No files found" ; \
else \
echo " Found $(wildcard *.o) " ; \
fi
第一个 if 语句工作正常
尝试删除 hello 文件
没有要删除的 hello 文件
而第二个产生这个:
/bin/sh: 1: main.o factorial.o: 未找到
找到 main.o factorial.o
我的问题是:为什么 make recipe 会产生有效的输出(这些文件确实存在)而 shell才不是?为什么 shell 甚至试图找到它们?
感谢您花时间阅读这个问题。这是我第一次来这里,所以如果我做错了什么,请告诉我
if main.o
与 if test -f main.o
非常不同。前者尝试 运行 命令 main.o
,而后者 运行 命令 test
。 if "main.o factorial.o"
是相似的,因为它尝试 运行 一个名为 main.o factorial.o
的命令,shell 正确地抱怨它找不到。您的 PATH 中不太可能有一个名为 main.o factorial.o
的文件(这是一个名称中带有 space 的文件)。
但是不要这样做。在取消链接之前检查文件是否存在绝对没有意义。存在固有的竞争条件。只需尝试删除该文件,并处理如果该文件不存在可能发生的错误。
编写 rm $(wildcard *.o)
并让 rm
为不存在的文件发出错误消息要容易得多。或者 rm -f $(wildcard *.o)
来抑制错误。如果你真的坚持遍历文件并检查,你可以这样做:
for f in $(wildcard *.o); do \
if ! test -f "$$f"; then echo "$$f" does not exist; \
else rm "$$f"; fi
但真的不值得。此外,这似乎毫无意义,因为 wildcard
只会扩展到存在的文件。 (但请注意,这表现出相同的竞争条件:通配符可能扩展为文件列表,但在通配符扩展和 rm
为 运行 之间可能会创建新文件。) ' 像这样使用 wildcard
。明确列出您要使用的文件。