Với:
FILES = $(shell ls)
thụt vào bên dưới all
như vậy, đó là một 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 coi là một biến make
, các biến này cần phải đượ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à FILES
sẽ được thiết lập để "đầu ra từ ls
" trước khi chạy bất kỳ lệnh nào tạo tệp .tgz. (Mặc dù như Kaz notes biến được tái mở rộng mỗi lần, vì vậy cuối cùng nó sẽ bao gồm các tập tin .tgz, một số làm cho các biến thể có FILES := ...
để tránh điều này, cho hiệu quả và/hoặc đúng đắn .)
Nếu FILES
là coi là một biến vỏ, bạn có thể đặt nó nhưng bạn cần phải làm điều đó trong vỏ ese, không có dấu cách, và trích dẫn:
all:
FILES="$(shell ls)"
Tuy nhiên, mỗi dòng được điều hành bởi một lớp vỏ riêng biệt, vì vậy biến này sẽ không tồn tại ở dòng tiếp theo, vì vậy, bạn phải sử dụng ngay lập tức:
FILES="$(shell ls)"; echo $$FILES
Đây là tất cả một chút ngớ ngẩn kể từ khi vỏ sẽ mở rộng *
(và khác biểu vỏ glob) cho bạn ở nơi đầu tiên, vì vậy bạn có thể chỉ:
echo *
như lệnh shell của bạn.
Cuối cùng, như một quy luật chung (không thực sự áp dụng đối với ví dụ này): như esperanto ghi chú trong các ý kiến, bằng cách sử dụng đầu ra từ ls
là 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 tin và đôi khi ngay cả những phiên bản của ls
; một số phiên bản ls
cố gắng khử trùng đầu ra trong một số trường hợp). Vì vậy, như là l0b0 và idelic lưu ý, nếu bạn đang sử dụng GNU, bạn có thể sử dụng $(wildcard)
và $(subst ...)
để tự hoàn thành mọi thứ bên trong make
(tránh bất kỳ vấn đề lạ nào trong tên tệp). (Trong sh
kịch bản, trong đó có phần công thức của makefiles, phương pháp khác là sử dụng find ... -print0 | xargs -0
để tránh vấp ngã trên khoảng trống, dòng mới, ký tự điều khiển, và vân vân.)
The GNU Make documentation notes further that POSIX make added ::=
assignment in 2012.Tôi đã không tìm thấy một liên kết tham khảo nhanh đến một tài liệu POSIX cho điều này, tôi cũng không biết off-hand mà make
biến thể hỗ trợ ::=
chuyển nhượng, mặc dù GNU làm làm ngày hôm nay, với ý nghĩa tương tự như :=
, ví dụ, làm nhiệm vụ ngay bây giờ với sự bành trướng.
Lưu ý rằng VAR := $(shell command args...)
cũng có thể được viết là VAR != command args...
trong một số biến thể make
, bao gồm tất cả biến thể GNU và BSD hiện đại theo như tôi biết. Những biến thể khác không có $(shell)
nên sử dụng VAR != command args...
là vượt trội trong cả hai là ngắn hơn và làm việc trong các biến thể hơn.
Cảm ơn. Tôi muốn sử dụng một lệnh phức tạp ('ls' với' sed' và cắt, ví dụ) và sau đó sử dụng kết quả trong rsync và các lệnh khác. Tôi có phải lặp lại câu lệnh dài dòng không? Tôi không thể lưu trữ các kết quả trong một biến Make nội bộ? –
Gnu làm có thể có một cách để làm điều đó, nhưng tôi chưa bao giờ sử dụng nó, và tất cả các makefiles khủng khiếp phức tạp, chúng tôi sử dụng chỉ cần sử dụng các biến shell và các lệnh shell one-liner khổng lồ được xây dựng với "; \" vào cuối mỗi dòng khi cần thiết. (Không thể có được mã hóa mã để làm việc với các chuỗi dấu chéo ngược ở đây, hmm) – torek
Ngoài ra, [thay vì 'ls'] (http://mywiki.wooledge.org/ParsingLs), bạn sẽ muốn sử dụng [' wildcard' make builtin] (https://www.gnu.org/software/make/manual/make.html#Wildcard-Function). – l0b0