Bash memperluas globbing di dalam Makefile


14

Saya ingin melakukan operasi pada semua file dalam folder tertentu yang tidak dimulai dengan awalan tertentu (katakanlah exclude_). Saya memiliki bash forloop dengan gumpalan diperpanjang yang terlihat seperti ini:

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

Di baris perintah, ini berfungsi dengan baik:

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

Tapi, ketika saya menggunakannya di makefile:

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

Saya mendapatkan kesalahan berikut:

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

Apakah ada beberapa pelarian yang perlu saya lewatkan?

Jawaban:


6
  1. Anda perlu mengatur extglob .
  2. Anda perlu memberitahu make untuk menggunakan bash, bukan sh.

Makefile:

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

2
Hmm. Untuk beberapa alasan, .SHELLFLAGSitu tidak berhasil untuk saya, tetapi menempatkan bendera secara langsung SHELL=/bin/bash -O extglob -c. Ada ide mengapa?
Timothy Jones

1
Mungkin Anda tidak menggunakan GNU make. Atau mungkin tidak perlu tanda kutip.
Ignacio Vazquez-Abrams

GNU Make 3.81, dan GNU bash, versi 4.1.2. Mencoba tanpa tanda kutip juga. Aneh.
Timothy Jones

Ngomong-ngomong, jawaban Anda menyelesaikannya untuk saya setelah saya menempatkan semuanya di satu baris. Terima kasih!
Timothy Jones

1
The .SHELLFLAGSvariabel ditambahkan dalam GNU make 3,82. Anda dapat memeriksa fitur mana yang ditambahkan di mana rilis melalui file NEWS: git.savannah.gnu.org/cgit/make.git/tree/NEWS
MadScientist

10

Akan lebih idiomatis dan lebih portabel untuk menyelesaikan ini dengan Make dan bukan dengan hack Bash. Bagaimana jika seseorang tidak menginstal Bash?

Bagaimanapun, inilah cara yang tepat untuk melakukannya di Make:

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

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

2

Ini cara yang lebih sederhana:

SHELL:=/bin/bash -O globstar

yang akan mengaktifkan opsi shell globstar (yang juga berfungsi pada BSD / OS X).


0

Tambahkan ini ke bagian atas Makefile:

SHELL := bash -O extglob

1
Tidak bekerja Versi di atas benar.
Desik
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.