Bash mở rộng toàn cầu bên trong một Makefile


14

Tôi muốn thực hiện một thao tác trên tất cả các tệp trong một thư mục cụ thể không bắt đầu bằng một tiền tố cụ thể (giả sử exclude_). Tôi có một forvòng lặp bash với một quả cầu mở rộng trông như thế này:

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

Trên dòng lệnh, điều này hoạt động tốt:

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

Nhưng, khi tôi sử dụng nó trong makefile:

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

Tôi nhận được lỗi sau đây:

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

Có một số lối thoát cần thiết mà tôi đã bỏ lỡ?

Câu trả lời:


6
  1. Bạn cần thiết lập extglob.
  2. Bạn cần nói làm cho sử dụng bash, không sh.

Trang điểm:

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

2
Hừm. Vì một số lý do, việc .SHELLFLAGSnày không hiệu quả với tôi, nhưng đặt cờ trực tiếp vào SHELL=/bin/bash -O extglob -c. Bất cứ ý tưởng tại sao?
Timothy Jones

1
Có lẽ bạn không sử dụng GNU make. Hoặc có thể nó không cần báo giá.
Ignacio Vazquez-Abrams

GNU Make 3.81 và GNU bash, phiên bản 4.1.2. Đã thử mà không có dấu ngoặc kép quá. Kỳ dị.
Timothy Jones

Dù sao, câu trả lời của bạn đã giải quyết nó cho tôi khi tôi đặt tất cả chúng trên một dòng. Cảm ơn!
Timothy Jones

1
Các .SHELLFLAGSbiến đã được bổ sung trong GNU make 3,82. Bạn có thể kiểm tra các tính năng đã được thêm vào trong bản phát hành qua tệp TIN TỨC: git.savannah.gnu.org/cgit/make.git/tree/NEWS
MadSellectist

10

Sẽ là thành ngữ hơn và dễ mang theo hơn để giải quyết vấn đề này bằng Make và không phải với hack Bash. Điều gì xảy ra nếu ai đó không cài đặt Bash?

Dù sao, đây là cách thích hợp để thực hiện trong Make:

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

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

2

Đây là một cách đơn giản hơn:

SHELL:=/bin/bash -O globstar

sẽ cho phép tùy chọn shell globalstar (cũng hoạt động trên BSD / OS X).


0

Thêm phần này vào đầu Makefile:

SHELL := bash -O extglob

1
Không hoạt động. Phiên bản trên là chính xác.
Desik
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.