makefile зависает при вызове командной оболочки - PullRequest
0 голосов
/ 03 января 2019

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

$ cat makefile
BASEDIR = ${HOME}/Downloads
MYDIR = ${BASEDIR}/ddd
all:
    var=${MYDIR}/m.txt
    @echo $(shell head -n 1 ${var})
#   @echo $(shell head -n 1 ${MYDIR}/m.txt)

Когда я пытаюсь использовать make, он просто зависает, и мне приходится его убивать. Когда я удаляю комментарий и использую команду head непосредственно на ${MYDIR}/m.txt, все работает нормально. Что я здесь не так делаю? Спасибо!

Ответы [ 2 ]

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

Не используйте функцию shell make в рецептах. Рецепты уже являются сценариями оболочки:

BASEDIR := $(HOME)/Downloads
MYDIR   := $(BASEDIR)/ddd

all:
    @var="$(MYDIR)/m.txt"; head -n 1 "$$var"

Примечания:

  • Рецепты расширяются до того, как они будут переданы оболочке. Здесь $(MYDIR) будет заменено чем-то вроде /home/doe/Downloads/ddd/m.txt. И именно поэтому $var не будет работать. Он будет расширяться как ar, если только не существует переменная make с именем v с непустым значением FOO, в этом случае $var будет расширяться как FOOar. $$var расширяется make как $var, синтаксис оболочки, который вы хотите.
  • Каждая строка рецепта выполняется независимой оболочкой. Таким образом, следующее не будет работать:

    all:
        @var="$(MYDIR)/m.txt"
        @head -n 1 "$$var"
    

    потому что назначение переменной оболочки (var="/home/doe/Downloads/ddd/m.txt") и расширение переменной оболочки (head -n 1 "$var") будут выполняться двумя разными оболочками. Если вы хотите использовать один оператор оболочки на строку, используйте продолжение строки:

    all:
        @var="$(MYDIR)/m.txt"; \
        head -n 1 "$$var"
    

    или

    all:
        @var="$(MYDIR)/m.txt" && \
        head -n 1 "$$var"
    
0 голосов
/ 03 января 2019

Не используйте переменные назначения в рецептах.В вашей команде head -n 1 ${var} выражение ${var} расширяется до нуля и, следовательно, head ожидает стандартного ввода.Следующий make-файл должен работать:

BASEDIR = ${HOME}/Downloads
MYDIR = ${BASEDIR}/ddd
var=${MYDIR}/m.txt
all:
    @echo $(shell head -n 1 ${var})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...