Спробуйте щось подібне у своєму 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
, (оскільки ми будемо використовувати його разом із -z
in curl
), і створює його, touch
якщо цього немає. Дотик створює його з позначкою часу 00:00 (12 ранку поточного дня).
Тоді він використовує опцію curl
s -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
).