Bash rozszerzył globowanie w pliku Makefile


15

Chcę wykonać operację na wszystkich plikach w określonym folderze, które nie zaczynają się od określonego prefiksu (powiedzmy exclude_). Mam forpętlę bash z rozszerzoną glob, która wygląda następująco:

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

W wierszu poleceń działa to dobrze:

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

Ale kiedy używam go w makefile:

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

Otrzymuję następujący błąd:

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

Czy jest jakaś niezbędna ucieczka, za którą tęskniłem?

Odpowiedzi:


7
  1. Musisz ustawić extglob.
  2. Musisz powiedzieć make używać bash, a nie sh.

Makefile:

SHELL=/bin/bash
.SHELLFLAGS="-O extglob -c"
 ...

2
Hmm Z jakiegoś powodu .SHELLFLAGSnie zadziałało to dla mnie, ale bezpośrednie włożenie flag SHELL=/bin/bash -O extglob -c. Jakieś pomysły dlaczego?
Timothy Jones

1
Może nie używasz GNU make. A może nie potrzebuje cytatów.
Ignacio Vazquez-Abrams

GNU Make 3.81 i GNU bash, wersja 4.1.2. Próbowałem też bez cytatów. Dziwne.
Timothy Jones

W każdym razie twoja odpowiedź rozwiązała dla mnie, kiedy umieściłem je wszystkie w jednym wierszu. Dzięki!
Timothy Jones

1
.SHELLFLAGSZmienna dodano GNU make 3,82. Możesz sprawdzić, które funkcje zostały dodane w których wydaniach za pomocą pliku NEWS: git.savannah.gnu.org/cgit/make.git/tree/NEWS
MadScientist

11

Bardziej idiomatyczne i przenośne byłoby rozwiązanie tego problemu za pomocą Make, a nie hacków Bash. Co jeśli ktoś nie ma zainstalowanego Bash?

W każdym razie oto właściwy sposób na zrobienie tego w Make:

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

target:
    for FILE in ${FOOFILES}; do echo $$FILE ; done

2

Oto prostszy sposób:

SHELL:=/bin/bash -O globstar

która włączy opcję powłoki globstar (która działa również na BSD / OS X).


0

Dodaj to na górze pliku Makefile:

SHELL := bash -O extglob

1
Nie działa Powyższa wersja jest poprawna.
Desik
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.