Спробуйте щось подібне у своєму Makefile:
.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
(зауважте: це Makefile, тому відступи - це вкладки, а не пробіли. Звичайно, важливо також, щоб після \рядків продовження не було пробілів - альтернативно позбудьтеся від зворотної косої лінії та зробіть її довгою, майже нечитабельна лінія)
Цей makeрецепт GNU спочатку перевіряє наявність файлу, який називається example.gz, (оскільки ми будемо використовувати його разом із -zin curl), і створює його, touchякщо цього немає. Дотик створює його з позначкою часу 00:00 (12 ранку поточного дня).
Тоді він використовує опцію curls -z( --time-cond) для завантаження, лише example.gzякщо вона була змінена з моменту останнього завантаження. -zможе надати фактичний вираз дати чи ім'я файлу. Якщо вказано ім'я файлу, воно використовуватиме час модифікації файлу як умову часу.
Після цього, якщо local.datйого немає, він створює його touch, використовуючи часову позначку, гарантовано старшу за мету example.gz. Це необхідно, тому що local.datмає існувати для наступної команди, яка використовується statдля отримання часової позначки mtime.
Потім, якщо example.gzє відмітка часу новіше local.dat, це труби example.gzв transmogrifyі перенаправляє висновок local.dat.
Нарешті, це робить речі з бухгалтерії та прибирання:
- він скорочується
example.gz(тому що потрібно зберігати лише часову позначку, а не весь файл)
touchес example.gzтак , що він має ту ж мітку часу , якlocal.dat
Ціль .PHONY забезпечує виконання local.datцілі завжди, навіть якщо файл цього імені вже існує.
Завдяки @Toby Speight за те, що в коментарях вказав, що моя оригінальна версія не працюватиме, і чому.
Крім того, якщо ви хочете передати файл безпосередньо в нього, transmogrifyне завантажуючи його у файлову систему спочатку:
.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
ПРИМІТКА. Це здебільшого неперевірене, тому можуть знадобитися деякі незначні зміни, щоб точно визначити синтаксис. Тут важливим є метод, а не рішення про копіювання та вставку вантажу.
Я використовую варіанти цього методу (тобто - touchвведення файлу часової мітки) makeпротягом десятиліть. Це працює, і зазвичай дозволяє мені уникати того, щоб писати власний код вирішення залежності в sh (хоча мені тут доводилося робити щось подібне stat --printf %Y).
Всі знають make, що це чудовий інструмент для компіляції програмного забезпечення ... ІМО - це також дуже занижений інструмент для системного адміністратора та сценаріїв.
-zПрапор, звичайно, передбачає , що віддалений сервер використовуєIf-Modified-Sinceзаголовки. Це може бути не обов'язково. Залежно від налаштування сервера, замість цього вам може знадобитися щось робитиETag, або перевіряючиCache-Controlзаголовки, або перевіряючи окремий файл контрольної суми (наприклад, якщо сервер надаєsha1sum).