我知道像this one问题,但我的问题是具体的makefile左右,具体gnumake的。
我有一个打印换行符和其他空白到标准输出的命令。我想捕捉输出到一个变量,然后在以后打印变量的文件。
例如生成文件:
OUTPUT=${shell cowsay hello}
all:
@echo "$(OUTPUT)" > output.txt
运行make后,output.txt中包含:
_______ < hello > ------- \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || ||
我希望它保留了空格,而是包含:
_______
< hello >
-------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
实际上,我使用的命令是不是cowsay,但它输出类似的空格和换行。
这是一个否定的答案,很遗憾。该GNU Make Manual states(强调):
所述
shell
函数执行该反引号在大多数壳执行相同的功能:它命令的扩展。这意味着它需要作为参数外壳命令,并评估该命令的输出。make
确实对结果的唯一处理是在每个新行(或回车/换行符对)转换为单个空格。如果有一个尾部(回车和)来换行它将简单地被移除。
我不认为eval
或define
会有所帮助。
唯一的变通办法,我可以看到的是存储cowsay hello
命令在一个变量,而不是命令的输出,如:
OUTPUT=$$(seq 5) # seq 5 replaces cowsay hello
all:
@echo "$(OUTPUT)" > output.txt
这种解决办法是坏的,如果cowsay hello
是昂贵的计算,或有副作用。第二解决办法是保持它的输出,但是替代换行符与任意字符(多个),使用例如sed
,然后加入换行符回来。例如:
OUTPUT=$(shell seq 5 | sed s/$$/xxx/) # add xxx to the end of each line
all:
@echo -n $(OUTPUT) ' ' | sed 's/xxx /\n/g' # replace xxx-space with line break
我想捕捉输出到一个变量,然后在以后打印变量的文件。
似乎没有被周围make
的机制办法在shell命令输出的换行转换成空间。即保持接近你原来的做法黑客攻击的位将是有壳转换换行符到一些不常见的词(如\1
)分配输出到变量时,然后把它它翻译回echo
-ING该变量的时候文件。事情是这样的:
OUTPUT=$(shell cowsay hello | tr '\n' '\1')
all:
@echo "$(OUTPUT)" | tr '\1' '\n' > output.txt
对我来说,这导致
$ make
$ cat output.txt
_______
< hello >
-------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
由于$(shell)
剔除了换行符,只需用另一个字符或图案更换。一回到化妆,更换一个新行该字符。
在这里,我选择了:
作为我的换行符替换。因人而异
define \n
endef
cow := $(subst :,${\n},$(shell cowsay hello | tr \\n :))
$(error [${cow}])
给予
$ make
Makefile:7: *** [ _______
< hello >
-------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
]. Stop.
你会发现它非常棘手的食谱,虽然使用${cow}
!