Versuchen Sie so etwas in Ihrem 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
(Hinweis: Dies ist ein Makefile, daher sind die Einrückungen Tabulatoren und keine Leerzeichen. Es ist auch wichtig, dass nach \
den Fortsetzungszeilen keine Leerzeichen mehr vorhanden sind. Alternativ können Sie die Backslash-Escapezeichen entfernen und es lang machen. fast unlesbare Zeile)
Dieses GNU- make
Rezept überprüft zunächst, ob eine aufgerufene Datei example.gz
vorhanden ist (da wir sie mit -z
in verwenden werden curl
), und erstellt sie mit, touch
wenn dies nicht der Fall ist. Die Berührung erstellt es mit einem Zeitstempel von 00:00 (12 Uhr des aktuellen Tages).
Dann verwendet es curl
‚s -z
( --time-cond
) Option , um nur herunterladen , example.gz
wenn es seit dem letzten Mal geändert wurde es heruntergeladen wurde. -z
kann ein tatsächlicher Datumsausdruck oder ein Dateiname angegeben werden. Wenn ein Dateiname angegeben wird, wird die Änderungszeit der Datei als Zeitbedingung verwendet.
Wenn local.dat
dies nicht der Fall ist, wird es anschließend mit touch
einem Zeitstempel erstellt, der garantiert älter als der von ist example.gz
. Dies ist erforderlich, da local.dat
der nächste Befehl vorhanden sein muss stat
, um seinen Zeitstempel mtime abzurufen.
Wenn dann example.gz
hat einen Zeitstempel neuer ist als local.dat
es Leitungen example.gz
in transmogrify
und leitet die Ausgabe zu local.dat
.
Schließlich erledigt es die Buchhaltung und Bereinigung:
- es wird abgeschnitten
example.gz
(weil Sie nur einen Zeitstempel und nicht die gesamte Datei behalten müssen)
touch
es example.gz
so, dass es den gleichen Zeitstempel wie hatlocal.dat
Das .PHONY-Ziel stellt sicher, dass das local.dat
Ziel immer ausgeführt wird, auch wenn die Datei mit diesem Namen bereits vorhanden ist.
Vielen Dank an @Toby Speight für den Hinweis in den Kommentaren, dass meine Originalversion nicht funktionieren würde und warum.
Alternativ, wenn Sie die Datei direkt transmogrify
weiterleiten möchten, ohne sie zuerst in das Dateisystem herunterzuladen:
.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
HINWEIS: Dies ist größtenteils ungetestet und erfordert möglicherweise einige geringfügige Änderungen, um die Syntax genau richtig zu machen. Das Wichtigste dabei ist die Methode, keine Copy-Paste-Cargo-Kult-Lösung.
Ich verwende seit Jahrzehnten Variationen dieser Methode (dh touch
eine Zeitstempeldatei) mit make
. Es funktioniert und ermöglicht mir normalerweise zu vermeiden, dass ich meinen eigenen Code für die Auflösung von Abhängigkeiten in sh schreiben muss (obwohl ich stat --printf %Y
hier etwas Ähnliches tun musste ).
Jeder weiß, dass make
es ein großartiges Tool zum Kompilieren von Software ist ... IMO ist es auch ein sehr unterbewertetes Tool für Systemadministrations- und Skriptaufgaben.
-z
Flag setzt natürlich voraus, dass der Remote-ServerIf-Modified-Since
Header verwendet. Dies muss nicht unbedingt der Fall sein. Abhängig von der Serverkonfiguration müssen Sie möglicherweise stattdessen etwas tunETag
, indem SieCache-Control
Header überprüfen oder eine separate Prüfsummendatei überprüfen (z. B. wenn der Server eine bereitstelltsha1sum
).