Bash estendido globbing dentro de um Makefile


14

Eu quero fazer uma operação em todos os arquivos em uma pasta específica que não iniciam com um prefixo específico (digamos exclude_). Eu tenho um forloop bash com uma glob estendida que se parece com isso:

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

Na linha de comando, isso funciona bem:

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

Mas quando eu o uso em um makefile:

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

Estou tendo o erro a seguir:

$ 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'

Existe alguma fuga necessária que eu perdi?

Respostas:


6
  1. Você precisa definir extglob.
  2. Você precisa dizer ao make para usar o bash, não o sh.

Makefile:

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

2
Hmm. Por alguma razão, .SHELLFLAGSisso não funcionou para mim, mas colocar as bandeiras diretamente SHELL=/bin/bash -O extglob -cfuncionou. Alguma idéia do porquê?
Timothy Jones

1
Talvez você não esteja usando o GNU make. Ou talvez não precise das aspas.
Ignacio Vazquez-Abrams

GNU Make 3.81 e GNU bash, versão 4.1.2. Tentei sem as aspas também. Esquisito.
Timothy Jones

De qualquer forma, sua resposta resolveu isso para mim quando eu os coloquei na mesma linha. Obrigado!
Timothy Jones

1
A .SHELLFLAGSvariável foi adicionada no GNU make 3.82. Você pode verificar quais recursos foram adicionados em quais lançamentos através do arquivo NEWS: git.savannah.gnu.org/cgit/make.git/tree/NEWS
MadScientist

10

Seria mais idiomático e mais portátil resolver isso com o Make e não com o Bash hacks. E se alguém não tiver o Bash instalado?

De qualquer forma, aqui está a maneira correta de fazer isso no Make:

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

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

2

Aqui está uma maneira mais simples:

SHELL:=/bin/bash -O globstar

que ativará a opção de shell globstar (que também funciona no BSD / OS X).


0

Adicione isso ao topo do Makefile:

SHELL := bash -O extglob

1
Não funciona A versão acima está correta.
Desik 21/09
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.