Экранирование # в функции gmake $ (shell) - PullRequest
0 голосов
/ 08 января 2020

У меня есть переменная окружения GITHUB_REFS, для которой я хочу выполнить некоторый bashism и записать результат в другую переменную GITHUB_BRANCH из make-файла GNU. Мой наивный подход выглядит так:

SHELL:=/bin/bash
GITHUB_BRANCH:=$(shell echo "${GITHUB_REF#refs/heads/}")

Если я запускаю bashism сам по себе, он работает нормально, однако при запуске вышеупомянутого make-файла происходит сбой с:

Makefile:2: *** unterminated call to function 'shell': missing ')'.  Stop.

Я попытался избежать # как \#, поскольку это правдоподобный преступник, и действительно, тогда Makefile работает, а bashism - нет. Двойное экранирование снова дает ту же ошибку.

Так как я могу это осуществить?

Ответы [ 3 ]

4 голосов
/ 08 января 2020

Вам также нужно удвоить знак доллара, чтобы передать его оболочке.

GITHUB_BRANCH:=$(shell echo "$${GITHUB_REF\#refs/heads/}")

Для чего стоит, это простое расширение параметра переносимо для любого достаточно современного sh, поэтому не в все это эксклюзивная функция Bash.

Конечно, make вполне может выполнить ту же замену, не вызывая внешний процесс.

GITHUB_BRANCH := $(patsubst refs/heads/%,%,${GITHUB_REF})
1 голос
/ 08 января 2020

Просто отметим, что это (необходимость избежать #) является ошибкой и будет исправлено в следующей версии GNU make. Если вы хотите, чтобы ваш make-файл был переносимым до / после исправления ошибки, вы должны скрыть его в такой переменной:

HASH := \#

foo := $(shell echo "${GITHUB_REF$(HASH)refs/heads/}")

Это будет работать во всех версиях GNU make.

1 голос
/ 08 января 2020

# можно экранировать с помощью \, но вы также забыли экранировать $.

Этот Makefile работает:

SHELL:=/bin/bash

foo := $(shell echo "$${SHELL\#/bin/}")

all:
    echo $(foo)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...