Prova qualcosa del genere nel tuo 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
(nota: questo è un Makefile, quindi i rientri sono tabulazioni, non spazi. Naturalmente. È anche importante che non ci siano spazi dopo le \
righe di continuazione - in alternativa sbarazzarsi delle backslash-escape e renderlo lungo, linea quasi illeggibile)
Questa make
ricetta GNU controlla prima che example.gz
esista un file chiamato (perché lo useremo con -z
in curl
), e lo crea con touch
se non lo fa. Il tocco lo crea con un timestamp di 00:00 (12:00 del giorno corrente).
Quindi utilizza curl
l' opzione -z
( --time-cond
) per scaricare solo example.gz
se è stato modificato dall'ultima volta in cui è stato scaricato. -z
può essere data un'espressione data effettiva o un nome file. Se viene assegnato un nome file, utilizzerà l'ora di modifica del file come condizione temporale.
Dopodiché, se local.dat
non esiste, lo crea con touch
, usando un timestamp garantito per essere più vecchio di quello di example.gz
. Ciò è necessario perché local.dat
deve esistere il comando successivo da utilizzare stat
per ottenere il timestamp mtime.
Poi, se example.gz
ha un timestamp più recente rispetto local.dat
, è tubi example.gz
in transmogrify
e reindirizza l'output local.dat
.
Infine, fa le cose di contabilità e pulizia:
- si tronca
example.gz
(perché è sufficiente mantenere un timestamp e non l'intero file)
touch
es in example.gz
modo che abbia lo stesso timestamp dilocal.dat
Il target .PHONY garantisce che il local.dat
target sia sempre eseguito, anche se il file con quel nome esiste già.
Grazie a @Toby Speight per aver sottolineato nei commenti che la mia versione originale non avrebbe funzionato, e perché.
In alternativa, se si desidera reindirizzare il file direttamente transmogrify
senza scaricarlo prima nel filesystem:
.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
NOTA: questo è per lo più non testato, quindi potrebbero essere necessarie alcune piccole modifiche per ottenere la sintassi esattamente corretta. La cosa importante qui è il metodo, non una soluzione cargo-cult copia-incolla.
Sto usando le varianti di questo metodo (ad esempio touch
-ing un file timestamp) con make
per decenni. Funziona e di solito mi consente di evitare di dover scrivere il mio codice di risoluzione della dipendenza in sh (anche se ho dovuto fare qualcosa di simile con stat --printf %Y
qui).
Tutti sanno che make
è un ottimo strumento per la compilazione di software ... IMO è anche uno strumento molto sottovalutato per le attività di amministrazione e scripting del sistema.
-z
flag, ovviamente, presuppone che il server remoto utilizzi leIf-Modified-Since
intestazioni. Questo potrebbe non essere necessariamente il caso. A seconda della configurazione del server, potresti invece dover fare qualcosa conETag
, o controllando leCache-Control
intestazioni, o controllando un file di checksum separato (ad esempio se il server fornisce asha1sum
).