Как сохранить пробелы при сохранении вывода команды в переменную Makefile? - PullRequest
0 голосов
/ 07 января 2019

Мне известны такие вопросы, как этот , но мой вопрос касается конкретно make-файла, в частности gnumake.

У меня есть команда, которая печатает разрывы строк и другие пробелы для стандартного вывода. Я хочу записать этот вывод в переменную, а затем распечатать переменную в файл.

Пример Makefile:

OUTPUT=${shell cowsay hello}

all:
    @echo "$(OUTPUT)" > output.txt

После запуска make файл output.txt содержит:

 _______  < hello >  -------          \   ^__^          \  (oo)\_______             (__)\       )\/\                 ||----w |                 ||     ||

Я хочу, чтобы он сохранил пробелы и вместо этого содержал:

 _______
< hello >
 -------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

Команда, которую я на самом деле использую, не является коровьей, но выводит аналогичные пробелы и переносы строк.

Ответы [ 3 ]

0 голосов
/ 07 января 2019

Я хочу записать этот вывод в переменную, а затем распечатать переменная в файл.

Похоже, нет никакого способа обойти механизм make для перевода новых строк в выходных данных команды оболочки в пробелы. Немного хака, который остается близким к вашему первоначальному подходу, будет заключаться в том, чтобы оболочка преобразовывала символы новой строки в какой-то необычный символ (например, \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 |
                ||     ||
0 голосов
/ 05 февраля 2019

Поскольку $(shell) удаляет новые строки, просто замените их другим символом или шаблоном. Вернувшись в make , замените этот символ новой строкой.

Здесь я выбрал : в качестве замены новой строки. YMMV

define \n


endef

cow := $(subst :,${\n},$(shell cowsay hello | tr \\n :))

$(error [${cow}])

Предоставление

$ make
Makefile:7: *** [ _______
< hello >
 -------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||
].  Stop.

Вам будет сложно использовать ${cow} в рецептах!

0 голосов
/ 07 января 2019

Это отрицательный ответ, к сожалению. GNU Make Manual устанавливает (выделение добавлено):

Функция 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
...