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?

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

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

2

Hier ist ein einfacher Weg:

SHELL:=/bin/bash -O globstar

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


0

Fügen Sie dies oben im Makefile hinzu:

SHELL := bash -O extglob

1
Funktioniert nicht Die obige Version ist korrekt.
Desik
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.