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?

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"
 ...

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

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).


0

Agregue esto a la parte superior del Makefile:

SHELL := bash -O extglob

1
No funciona La versión anterior es correcta.
Desik
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.