How to preserve whitespace when saving command output to a Makefile variable?
This is a negative answer, unfortunately. The GNU Make Manual states (emphasis added):
The
shell
function performs the same function that backquotes perform in most shells: it does command expansion. This means that it takes as an argument a shell command and evaluates to the output of the command. The only processingmake
does on the result is to convert each newline (or carriage-return / newline pair) to a single space. If there is a trailing (carriage-return and) newline it will simply be removed.
I don't think that eval
or define
will help.
The only work-around that I can see is to store the cowsay hello
command in a variable, instead of the command's output, as in:
OUTPUT=$$(seq 5) # seq 5 replaces cowsay hello
all:
@echo "$(OUTPUT)" > output.txt
This work-around is bad if cowsay hello
is expensive to calculate, or has side-effects. A second work-around is to keep its output, but replace the line-breaks with any arbitrary character(s), using for example sed
, and then adding the line-breaks back. For example:
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
I want to capture that output into a variable and then later print the variable to a file.
There does not seem to be a way around make
's mechanism to translate newlines in the shell command output into spaces. A bit of a hack that stays close to your original approach would be to have the shell convert newlines into some uncommon character (like \1
) when assigning the output to the variable and then have it translate it back when echo
-ing that variable to the file. Something like this:
OUTPUT=$(shell cowsay hello | tr '\n' '\1')
all:
@echo "$(OUTPUT)" | tr '\1' '\n' > output.txt
For me, this results in
$ make
$ cat output.txt
_______
< hello >
-------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||