Bash hat das Globbing in einem Makefile verlängert

14

Ich möchte eine Operation für alle Dateien in einem bestimmten Ordner ausführen, die nicht mit einem bestimmten Präfix beginnen (z exclude_. B. ). Ich habe eine Bash- forSchleife mit einem erweiterten Glob, der so aussieht:

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

Auf der Kommandozeile funktioniert das gut:

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

Aber wenn ich es in einem Makefile benutze:

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

Ich erhalte folgenden Fehler:

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

Gibt es eine notwendige Fluchtmöglichkeit, die ich verpasst habe?

Timothy Jones
quelle

Antworten:

6
  1. Sie müssen einstellen extglob.
  2. Sie müssen make sagen, dass Sie bash verwenden sollen, nicht sh.

Makefile:

SHELL=/bin/bash
.SHELLFLAGS="-O extglob -c"
 ...
Ignacio Vazquez-Abrams
quelle
2
Hmm. Aus irgendeinem Grund .SHELLFLAGSfunktionierte das nicht für mich, aber das Setzen der Flaggen direkt in SHELL=/bin/bash -O extglob -ctat. Irgendwelche Ideen warum?
Timothy Jones
1
Vielleicht benutzt du nicht GNU make. Oder vielleicht braucht es die Anführungszeichen nicht.
Ignacio Vazquez-Abrams
GNU Make 3.81 und GNU Bash, Version 4.1.2. Versucht auch ohne Anführungszeichen. Seltsam.
Timothy Jones
Wie auch immer, Ihre Antwort hat es für mich gelöst, sobald ich sie alle in eine Zeile gesetzt habe. Vielen Dank!
Timothy Jones
1
Die .SHELLFLAGSVariable wurde in GNU make 3.82 hinzugefügt. Über die NEWS-Datei können Sie überprüfen, welche Funktionen in welchen Releases hinzugefügt wurden: git.savannah.gnu.org/cgit/make.git/tree/NEWS
MadScientist
10

Es wäre idiomatischer und portabler, dies mit Make und nicht mit Bash-Hacks zu lösen. Was ist, wenn jemand Bash nicht installiert hat?

Wie auch immer, hier ist der richtige Weg , dies in Make zu tun:

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

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

Hier ist ein einfacher Weg:

SHELL:=/bin/bash -O globstar

Dadurch wird die Globstar-Shell-Option aktiviert (funktioniert auch unter BSD / OS X).

Kenorb
quelle
0

Fügen Sie dies oben im Makefile hinzu:

SHELL := bash -O extglob
Geremia
quelle
1
Funktioniert nicht Die obige Version ist korrekt.
Desik