Bash extendió el globbing dentro de un Makefile

14

Quiero hacer una operación en todos los archivos en una carpeta particular que no comienzan con un prefijo particular (por ejemplo exclude_). Tengo un forbucle bash con un globo extendido que se ve así:

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

En la línea de comando, esto funciona bien:

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

Pero, cuando lo uso en un archivo MAKE:

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

Obtuve el siguiente error:

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

¿Hay algún escape necesario que me haya perdido?

Timothy Jones
fuente

Respuestas:

6
  1. Tienes que configurar extglob.
  2. Necesitas decirle a make que use bash, no sh.

Makefile:

SHELL=/bin/bash
.SHELLFLAGS="-O extglob -c"
 ...
Ignacio Vazquez-Abrams
fuente
2
Hmm Por alguna razón .SHELLFLAGS, no funcionó para mí, pero poner las banderas directamente SHELL=/bin/bash -O extglob -csí. Alguna idea de por qué?
Timothy Jones
1
Tal vez no estés usando GNU make. O tal vez no necesita las comillas.
Ignacio Vazquez-Abrams
GNU Make 3.81 y GNU bash, versión 4.1.2. Intenté sin las comillas también. Extraño.
Timothy Jones
De todos modos, su respuesta me lo resolvió una vez que los puse todos en la misma línea. ¡Gracias!
Timothy Jones
1
La .SHELLFLAGSvariable se agregó en GNU make 3.82. Puede verificar qué características se agregaron en qué versiones a través del archivo NEWS: git.savannah.gnu.org/cgit/make.git/tree/NEWS
MadScientist
11

Sería más idiomático y más portátil resolver esto con Make y no con los hacks de Bash. ¿Qué pasa si alguien no tiene Bash instalado?

De todos modos, aquí está la forma correcta de hacerlo en Make:

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

target:
    for FILE in ${FOOFILES}; do echo $$FILE ; done
Timothy Jones
fuente
2

Aquí hay una manera más simple:

SHELL:=/bin/bash -O globstar

que habilitará la opción de shell globstar (que también funciona en BSD / OS X).

kenorb
fuente
0

Agregue esto a la parte superior del Makefile:

SHELL := bash -O extglob
Geremia
fuente
1
No funciona La versión anterior es correcta.
Desik