Bash расширил шарикование внутри Makefile


14

Я хочу сделать операцию со всеми файлами в определенной папке, которые не начинаются с определенного префикса (скажем exclude_). У меня есть forцикл bash с расширенным глобусом, который выглядит следующим образом:

for FILE in foo/bar/!(exclude_*) ; do echo $FILE ; done

В командной строке это работает нормально:

 $ for FILE in foo/bar/!(exclude_*) ; do echo $FILE ; done
 foo/bar/apple
 foo/bar/pear
 foo/bar/banana

Но когда я использую его в make-файле:

target:
    for FILE in foo/bar/!(exclude_*) ; do echo $$FILE ; done

Я получаю следующую ошибку:

$ make
for FILE in foo/bar/!(exclude_*) ; do echo $FILE ; done
/bin/sh: -c: line 0: syntax error near unexpected token `('
/bin/sh: -c: line 0: `for FILE in foo/bar/!(exclude_*) ; do echo $FILE ; done'

Есть ли какие-то необходимые побеги, которые я пропустил?

Ответы:


6
  1. Вам нужно установить extglob.
  2. Вы должны указать make использовать bash, а не sh.

Makefile:

SHELL=/bin/bash
.SHELLFLAGS="-O extglob -c"
 ...

2
Хм. По какой-то причине у .SHELLFLAGSменя это не сработало, но поставить флаги прямо у меня SHELL=/bin/bash -O extglob -cполучилось. Есть идеи почему?
Тимоти Джонс

1
Может быть, вы не используете GNU make. Или, может быть, он не нуждается в кавычках.
Игнасио Васкес-Абрамс

GNU Make 3.81 и GNU bash, версия 4.1.2. Пробовал без кавычек тоже. Weird.
Тимоти Джонс

В любом случае, ваш ответ решил это для меня, как только я поместил их все в одну строку. Благодарность!
Тимоти Джонс

1
.SHELLFLAGSПеременная была добавлена в GNU Make 3.82. Вы можете проверить, какие функции были добавлены в какие выпуски, с помощью файла NEWS: git.savannah.gnu.org/cgit/make.git/tree/NEWS
MadScientist,

11

Это было бы более идиоматичным и более портативным, чтобы решить это с помощью Make, а не с помощью Bash-хаков. Что делать, если у кого-то не установлен Bash?

В любом случае, вот правильный способ сделать это в Make:

FOOFILES = $(filter-out foo/bar/exclude_%,$(wildcard foo/bar/*))

target:
    for FILE in ${FOOFILES}; do echo $$FILE ; done

2

Вот более простой способ:

SHELL:=/bin/bash -O globstar

который включит опцию оболочки globstar (которая также работает на BSD / OS X).


0

Добавьте это в начало Makefile:

SHELL := bash -O extglob

1
Не работает Вышеуказанная версия верна.
Desik
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.