我试图使用的结果ls
在其他命令(例如回声,rsync的):
all:
<Building, creating some .tgz files - removed for clarity>
FILES = $(shell ls)
echo $(FILES)
但我得到:
make
FILES = Makefile file1.tgz file2.tgz file3.tgz
make: FILES: No such file or directory
make: *** [all] Error 1
我已经尝试使用echo $$FILES
, echo ${FILES}
和echo $(FILES)
,没有运气。
附:
FILES = $(shell ls)
下面缩进all
这样的,它是一个构建命令。 所以这个扩展$(shell ls)
然后尝试运行命令FILES ...
。
如果FILES
应该是一个make
的变量,这些变量需要的配方部分,例如外被分配:
FILES = $(shell ls)
all:
echo $(FILES)
当然,这意味着FILES
将被设置为“从输出ls
”运行任何创建.tgz的文件的命令之前 。 (虽然作为卡兹指出变量每次再膨胀,这样最终会包括.tgz的文件;有的使变种有FILES := ...
,以避免这种情况,为了提高效率和/或正确性1)。
如果FILES
应该是一个shell变量,你可以设置它,但你需要做的是在壳ESE,没有空格,并引用:
all:
FILES="$(shell ls)"
然而,每一行由单独的shell中运行,所以这个变量将无法生存到下一行,这样,那么你必须立刻使用它:
FILES="$(shell ls)"; echo $$FILES
这毕竟是一个有点傻,因为外壳将扩大*
你(和其他壳水珠表达式)摆在首位,所以你可以:
echo *
作为你的shell命令。
最后,作为一般规则(不是真的适用于本示例):作为世界语在评论中指出,使用从输出ls
不是完全可靠的(一些细节依赖于文件名,有时甚至版本的ls
;某些版本的ls
尝试消毒在某些情况下输出)。 因此, l0b0和idelic的注意,如果你使用GNU让你可以使用$(wildcard)
和$(subst ...)
来完成这里的一切都make
自己(避免“在文件名字符怪异”的问题的话)。 (在sh
脚本,包括生成文件的配方部分,另一种方法是使用find ... -print0 | xargs -0
以避免绊倒坯料,换行,控制字符,等等)。
1 的GNU制作文件进一步指出,POSIX使加::=
分配在2012年 。 我还没有找到一个快速参考链接到了这个POSIX文件,也不知道离手这make
变种支持::=
分配,虽然GNU做出今天这样,有相同的含义:=
,即做作业现在与扩张。
需要注意的是VAR := $(shell command args...)
也可以拼VAR != command args...
在几个make
变体,包括所有的现代GNU和BSD据我所知变种。 这些其他变体没有$(shell)
因此使用VAR != command args...
在这两个长度较短,在更多的变种工作优越。
此外,除了托雷克的回答是:有一点突出的是,您使用的是惰性计算宏观分配。
如果你在使用GNU make,使用:=
赋值,而不是=
。 这种分配导致右侧被立即展开,并存储在左边的变量。
FILES := $(shell ...) # expand now; FILES is now the result of $(shell ...)
FILES = $(shell ...) # expand later: FILES holds the syntax $(shell ...)
如果使用=
赋值,这意味着每一个出现$(FILES)
将扩展$(shell ...)
语法,因此调用shell命令。 这会让你的化妆工作运行速度较慢,甚至有一些令人惊讶的结果。