Với:
FILES = $(shell ls)
thụt vào bên dưới all
như vậy, đó là lệnh xây dựng. Vì vậy, điều này mở rộng $(shell ls)
, sau đó cố gắng chạy lệnh FILES ...
.
Nếu FILES
được cho là một make
biến, các biến này cần được chỉ định bên ngoài phần công thức, ví dụ:
FILES = $(shell ls)
all:
echo $(FILES)
Tất nhiên, điều đó có nghĩa là nó FILES
sẽ được đặt thành "đầu ra từ ls
" trước khi chạy bất kỳ lệnh nào tạo tệp .tgz. (Mặc dù Kaz lưu ý rằng biến được mở rộng lại mỗi lần, vì vậy cuối cùng nó sẽ bao gồm các tệp .tgz; một số biến thể phải FILES := ...
tránh điều này, vì hiệu quả và / hoặc tính đúng đắn. 1 )
Nếu FILES
được cho là một biến shell, bạn có thể đặt nó nhưng bạn cần thực hiện trong shell-ese, không có khoảng trắng và được trích dẫn:
all:
FILES="$(shell ls)"
Tuy nhiên, mỗi dòng được chạy bởi một shell riêng biệt, do đó, biến này sẽ không tồn tại đến dòng tiếp theo, vì vậy bạn phải sử dụng nó ngay lập tức:
FILES="$(shell ls)"; echo $$FILES
Điều này hơi ngớ ngẩn vì shell sẽ mở rộng *
(và các biểu thức shell khác) cho bạn ngay từ đầu, vì vậy bạn có thể chỉ cần:
echo *
như lệnh shell của bạn.
Cuối cùng, như một quy tắc chung (không thực sự áp dụng cho ví dụ này): như ghi chú của esperanto trong nhận xét, việc sử dụng đầu ra từ ls
không hoàn toàn đáng tin cậy (một số chi tiết phụ thuộc vào tên tệp và đôi khi thậm chí là phiên bản của ls
; một số phiên bản ls
cố gắng làm sạch đầu ra trong vài trường hợp). Vì vậy, như l0b0 và lưu ý idelic , nếu bạn đang sử dụng GNU, bạn có thể sử dụng $(wildcard)
và $(subst ...)
hoàn thành mọi thứ bên trong make
chính nó (tránh mọi vấn đề "ký tự lạ trong tên tệp"). (Trong sh
tập lệnh, bao gồm cả phần công thức của các tệp trang điểm, một phương pháp khác là sử dụng find ... -print0 | xargs -0
để tránh vấp phải khoảng trống, dòng mới, ký tự điều khiển, v.v.)
1 GNU Ghi chú thêm tài liệu rằng POSIX thực hiện thêm ::=
nhiệm vụ vào năm 2012 . Tôi không tìm thấy liên kết tham chiếu nhanh đến tài liệu POSIX cho việc này, cũng như không biết make
biến thể nào hỗ trợ ::=
việc gán, mặc dù GNU thực hiện ngày nay, với ý nghĩa tương tự như :=
thực hiện việc gán ngay bây giờ với mở rộng.
Lưu ý rằng VAR := $(shell command args...)
cũng có thể được đánh vần VAR != command args...
trong một số make
biến thể, bao gồm tất cả các biến thể GNU và BSD hiện đại theo như tôi biết. Các biến thể khác không có $(shell)
vì vậy việc sử dụng VAR != command args...
vượt trội hơn cả về thời gian ngắn hơn và hoạt động ở nhiều biến thể hơn.
ls
vớised
và cắt) và sau đó sử dụng kết quả trong rsync và các lệnh khác. Tôi có phải lặp đi lặp lại lệnh dài dòng không? Tôi không thể lưu trữ kết quả trong biến Make nội bộ?