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.