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 makethức kiểm tra đầu tiên mà một tập tin gọi là example.gztồn tại (vì chúng ta sẽ sử dụng nó với -ztrong curl), và tạo ra nó với touchnế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.gznếu nó đã được sửa đổi kể từ lần cuối cùng nó được tải xuống. -zcó 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.datkhông tồn tại, nó tạo ra nó bằng touchcá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.datphả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.gzcó dấu thời gian mới hơn local.dat, nó sẽ dẫn example.gzvào transmogrifyvà 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)
touches 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.datmụ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 transmogrifymà 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à - touchmột tệp dấu thời gian) maketrong 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 makelà 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.
-zcờ, tất nhiên, giả định rằng các máy chủ từ xa sử dụngIf-Modified-Sincetiê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ì đóETaghoặc bằng cách kiểm traCache-Controlcá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).