Hãy thử một cái gì đó như thế này trong Makefile của bạn:
.PHONY: local.dat
local.dat:
[ -e example.gz ] || touch -d '00:00' example.gz
curl -z example.gz -s http://example.org/example.gz -o example.gz
[ -e $@ ] || touch -d 'yesterday 00:00' $@
if [ "$(shell stat --printf '%Y' example.gz)" \
-gt "$(shell stat --printf '%Y' $@)" ] ; then \
zcat example.gz | transmogrify >$@ ; \
fi
truncate -s 0 example.gz
touch -r $@ example.gz
.. (lưu ý: đây là một Makefile, vì vậy indents các tab, không gian dĩ nhiên Nó cũng quan trọng là không có dấu cách sau \
trên dòng tiếp nối - cách khác thoát khỏi dấu chéo ngược-thoát và làm cho nó trở thành một dài, dòng gần như không thể đọc được)
Đây GNU make
thức kiểm tra đầu tiên mà một tập tin gọi là example.gz
tồn tại (vì chúng ta sẽ sử dụng nó với -z
trong curl
), và tạo ra nó với touch
nếu nó không. Cảm ứng tạo ra nó với dấu thời gian là 00:00 (12 giờ sáng của ngày hiện tại).
Sau đó, nó sử dụng curl
's -z
( --time-cond
) tùy chọn để chỉ tải example.gz
nếu nó đã được sửa đổi kể từ lần cuối cùng nó được tải xuống. -z
có thể được cung cấp một biểu thức ngày thực tế, hoặc một tên tệp. Nếu được đặt tên tệp, nó sẽ sử dụng thời gian sửa đổi của tệp làm điều kiện thời gian.
Sau đó, nếu local.dat
không tồn tại, nó tạo ra nó bằng touch
cách sử dụng dấu thời gian được đảm bảo cũ hơn so với example.gz
. Điều này là cần thiết bởi vì local.dat
phải tồn tại cho lệnh tiếp theo được sử dụng stat
để lấy dấu thời gian mtime của nó.
Sau đó, nếu example.gz
có dấu thời gian mới hơn local.dat
, nó sẽ dẫn example.gz
vào transmogrify
và chuyển hướng đầu ra local.dat
.
Cuối cùng, nó thực hiện công việc kế toán và dọn dẹp:
- nó cắt ngắn
example.gz
(vì bạn chỉ cần giữ dấu thời gian chứ không phải toàn bộ tệp)
touch
es example.gz
để nó có cùng dấu thời gian nhưlocal.dat
Mục tiêu .PHONY đảm bảo rằng local.dat
mục tiêu luôn được thực thi, ngay cả khi tệp của tên đó đã tồn tại.
Cảm ơn @Toby Speight đã chỉ ra trong các nhận xét rằng phiên bản gốc của tôi sẽ không hoạt động, và tại sao.
Ngoài ra, nếu bạn muốn dẫn tập tin trực tiếp vào transmogrify
mà không tải nó xuống hệ thống tập tin trước:
.PHONY: local.dat
local.dat:
[ -e example.gz ] || touch -d '00:00' example.gz
[ -e $@ ] || touch -d 'yesterday 00:00' $@
if [ "$(shell stat --printf '%Y' example.gz)" \
-gt "$(shell stat --printf '%Y' $@)" ] ; then \
curl -z example.gz -s http://example.org/example.gz | transmogrify >$@ ; \
fi
touch -r $@ example.gz
LƯU Ý: điều này chủ yếu chưa được kiểm tra nên có thể yêu cầu một số thay đổi nhỏ để có được cú pháp chính xác. Điều quan trọng ở đây là phương pháp, không phải là giải pháp sùng bái hàng hóa sao chép.
Tôi đã sử dụng các biến thể của phương pháp này (tức là - touch
một tệp dấu thời gian) make
trong nhiều thập kỷ. Nó hoạt động và thường cho phép tôi tránh phải viết mã độ phân giải phụ thuộc của riêng mình vào sh (mặc dù tôi đã phải làm một cái gì đó tương tự stat --printf %Y
ở đây).
Mọi người đều biết make
là một công cụ tuyệt vời để biên dịch phần mềm ... IMO nó cũng là một công cụ được đánh giá rất thấp cho quản trị hệ thống và các tác vụ kịch bản.
-z
cờ, tất nhiên, giả định rằng các máy chủ từ xa sử dụngIf-Modified-Since
tiêu đề. Điều này có thể không nhất thiết là trường hợp. Tùy thuộc vào thiết lập máy chủ, thay vào đó, bạn có thể cần phải làm gì đóETag
hoặc bằng cách kiểm traCache-Control
các tiêu đề hoặc bằng cách kiểm tra một tệp tổng kiểm tra riêng (ví dụ: nếu máy chủ cung cấp asha1sum
).