sff*_*ffc 5 whitespace makefile gnu-make
我知道类似这样的问题,但是我的问题专门关于makefile,尤其是gnumake。
我有一个命令可以打印换行符和其他空格以标准化。我想将输出捕获到变量中,然后再将变量打印到文件中。
示例文件:
OUTPUT=${shell cowsay hello}
all:
@echo "$(OUTPUT)" > output.txt
Run Code Online (Sandbox Code Playgroud)
运行make之后,output.txt包含:
_______ < hello > ------- \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || ||
Run Code Online (Sandbox Code Playgroud)
我希望它保留空格,而包含:
_______
< hello >
-------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
Run Code Online (Sandbox Code Playgroud)
我实际上使用的命令不是说说的,但是它输出类似的空格和换行符。
不幸的是,这是一个否定的答案。GNU Make 手册指出(强调是添加的):
该
shell函数执行的功能与大多数 shell 中的反引号执行的功能相同:它执行命令扩展。这意味着它接受 shell 命令作为参数并计算该命令的输出。make对结果的唯一处理是将每个换行符(或回车符/换行符对)转换为单个空格。如果有尾随(回车符和)换行符,它将被简单地删除。
我认为这没有eval帮助define。
我能看到的唯一解决方法是将cowsay hello 命令存储在变量中,而不是命令的输出,如下所示:
OUTPUT=$$(seq 5) # seq 5 replaces cowsay hello
all:
@echo "$(OUTPUT)" > output.txt
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
我想将该输出捕获到一个变量中,然后将该变量打印到一个文件中。
似乎没有办法绕过 的make机制将 shell 命令输出中的换行符转换为空格。与原始方法保持接近的一个技巧是,在将输出分配给变量时,让 shell 将换行符转换为一些不常见的字符(例如),然后在将该变量写入文件\1时将其转换回来。echo像这样的东西:
OUTPUT=$(shell cowsay hello | tr '\n' '\1')
all:
@echo "$(OUTPUT)" | tr '\1' '\n' > output.txt
Run Code Online (Sandbox Code Playgroud)
对我来说,这导致
$ make
$ cat output.txt
_______
< hello >
-------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
Run Code Online (Sandbox Code Playgroud)