使用:
FILES = $(shell ls)
这是一个构建命令,所有缩进在all
下面的内容都是如此。因此,它会展开$(shell ls)
,然后尝试运行命令FILES ...
。
如果FILES
应该是一个make
变量,这些变量需要在配方部分之外进行赋值,例如:
FILES = $(shell ls)
all:
echo $(FILES)
当然,这意味着在运行任何创建.tgz文件的命令之前,“FILES”将被设置为“来自‘ls’的输出”。(尽管如
Kaz notes所述,该变量每次都会重新扩展,因此最终将包括.tgz文件;一些make变体具有“FILES:=...”以避免这种情况,以提高效率和/或正确性。
1)
如果“FILES”应该是一个shell变量,则可以设置它,但必须使用无空格的shell语言进行引用。
all:
FILES="$(shell ls)"
然而,每行都由单独的 shell 运行,因此这个变量将不会在下一行生效,所以你必须立即使用它:
FILES="$(shell ls)"; echo $$FILES
这有点儿愚蠢,因为 shell 会在首次展开 *
(以及其他 shell glob 表达式)时为您完成,所以您只需:
echo *
作为您的Shell命令。
最后,作为一般规则(不适用于此示例):正如esperanto在评论中指出的那样,使用ls
的输出并不完全可靠(某些细节取决于文件名,有时甚至取决于ls
的版本;某些版本的ls
尝试在某些情况下对输出进行清理)。因此,正如l0b0和idelic所指出的那样,如果您正在使用GNU make,则可以使用$(wildcard)
和$(subst ...)
来完成make
内部的所有操作(避免任何“文件名中的奇怪字符”问题)。 (在sh
脚本中,包括makefile的配方部分,另一种方法是使用find ... -print0 | xargs -0
来避免空格、换行符、控制字符等问题。)
1GNU Make文档进一步指出,POSIX make在2012年添加了::=
赋值语句。我没有找到一个快速参考链接来查看POSIX文件的内容,也不知道哪些make
变种支持::=
赋值语句,尽管GNU make今天支持,其含义与:=
相同,即立即执行带有扩展的赋值语句。
请注意,在几个make
变种中,包括所有现代GNU和BSD变种,VAR := $(shell command args...)
也可以写作VAR != command args...
。这些其他变种没有$(shell)
,因此使用VAR != command args...
既更短又适用于更多变种。
通配符
make内置函数,而不是使用ls
命令。 - l0b0FILE = $(shell ls *.c | sed -e "s^fun^bun^g")
- William Morrismake
而不需要使用shell来实现这个功能:FILE = $(subst fun,bun,$(wildcard *.c))
。 - Idelic