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 makericetta GNU controlla prima che example.gzesista un file chiamato (perché lo useremo con -zin curl), e lo crea con touchse non lo fa. Il tocco lo crea con un timestamp di 00:00 (12:00 del giorno corrente).
Quindi utilizza curll' opzione -z( --time-cond) per scaricare solo example.gzse è stato modificato dall'ultima volta in cui è stato scaricato. -zpuò 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.datnon esiste, lo crea con touch, usando un timestamp garantito per essere più vecchio di quello di example.gz. Ciò è necessario perché local.datdeve esistere il comando successivo da utilizzare statper ottenere il timestamp mtime.
Poi, se example.gzha un timestamp più recente rispetto local.dat, è tubi example.gzin transmogrifye 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)
touches in example.gzmodo che abbia lo stesso timestamp dilocal.dat
Il target .PHONY garantisce che il local.dattarget 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 transmogrifysenza 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 makeper 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 %Yqui).
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.
-zflag, ovviamente, presuppone che il server remoto utilizzi leIf-Modified-Sinceintestazioni. Questo potrebbe non essere necessariamente il caso. A seconda della configurazione del server, potresti invece dover fare qualcosa conETag, o controllando leCache-Controlintestazioni, o controllando un file di checksum separato (ad esempio se il server fornisce asha1sum).