Bash bir Makefile içinde genişletilmiş globbing


15

Belirli bir klasördeki belirli bir önekle (say exclude_) başlamayan tüm dosyalar üzerinde işlem yapmak istiyorum . Böyle bir forgenişletilmiş glob ile bash döngü var:

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

Komut satırında, bu iyi çalışır:

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

Ancak, bir makefile kullandığımda:

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

Aşağıdaki hatayı alıyorum:

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

Kaçırdığım bazı kaçışlar var mı?

Yanıtlar:


7
  1. Ayarlamanız gerekiyor extglob.
  2. Sh kullanmak için bash yapmak için söylemelisin.

Makefile:

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

2
Hmm. Nedense .SHELLFLAGSbenim için işe yaramadı, ama bayrakları doğrudan koymak işe SHELL=/bin/bash -O extglob -cyaradı. Neden herhangi bir fikir?
Timothy Jones

1
Belki GNU marka kullanmıyorsunuzdur. Ya da alıntılara ihtiyacı yoktur.
Ignacio Vazquez-Abrams

GNU Make 3.81 ve GNU bash, sürüm 4.1.2. Tırnak işaretleri olmadan da denedim. Tuhaf.
Timothy Jones

Her neyse, hepsini tek bir satıra koyduğumda cevabınız benim için çözdü. Teşekkürler!
Timothy Jones

1
.SHELLFLAGSDeğişken GNU marka 3,82 eklendi. Hangi özelliklerin eklendiğini NEWS dosyası üzerinden kontrol edebilirsiniz: git.savannah.gnu.org/cgit/make.git/tree/NEWS
MadScientist

11

Bunu Bash hack'leriyle değil Make ile çözmek daha deyimsel ve daha taşınabilir olurdu. Birisi Bash yüklü değilse ne olur?

Her neyse, Make'da yapmanın doğru yolu :

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

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

2

İşte daha basit bir yol:

SHELL:=/bin/bash -O globstar

globstar kabuk seçeneğini etkinleştirecektir (BSD / OS X üzerinde de çalışır).


0

Bunu Makefile'nin üstüne ekleyin:

SHELL := bash -O extglob

1
Çalışmıyor. Yukarıdaki sürüm doğrudur.
Desik
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.