Essayez quelque chose comme ça dans votre 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
(Remarque: il s'agit d'un Makefile, donc les retraits sont des tabulations, pas des espaces. Bien sûr. Il est également important qu'il n'y ait pas d'espaces après les \
lignes de continuation - vous pouvez également vous débarrasser des échappements antislash et en faire un long, ligne presque illisible)
Cette make
recette GNU vérifie d'abord qu'un fichier appelé example.gz
existe (parce que nous allons l'utiliser avec -z
in curl
), et le crée avec touch
si ce n'est pas le cas. Le toucher le crée avec un horodatage de 00h00 (12h00 du jour actuel).
Ensuite, il utilise curl
l' option 's -z
( --time-cond
) pour télécharger uniquementexample.gz
s'il a été modifié depuis le dernier téléchargement. -z
peut recevoir une expression de date réelle ou un nom de fichier. Si on lui donne un nom de fichier, il utilisera l'heure de modification du fichier comme condition temporelle.
Après cela, s'il local.dat
n'existe pas, il le crée avec touch
, en utilisant un horodatage garanti comme étant plus ancien que celui de example.gz
. Ceci est nécessaire car local.dat
doit exister pour que la prochaine commande puisse être utiliséestat
pour obtenir son horodatage mtime.
Ensuite, si example.gz
a un horodatage plus récent que local.dat
, il les tuyaux example.gz
dans transmogrify
et réoriente la sortielocal.dat
.
Enfin, il fait la comptabilité et le nettoyage:
- il tronque
example.gz
(car il vous suffit de garder un horodatage, et non tout le fichier)
touch
es example.gz
pour qu'il ait le même horodatage quelocal.dat
La cible .PHONY garantit que la local.dat
cible est toujours exécutée, même si le fichier de ce nom existe déjà.
Merci à @Toby Speight d'avoir souligné dans les commentaires que ma version originale ne fonctionnerait pas, et pourquoi.
Alternativement, si vous souhaitez diriger le fichier directement transmogrify
sans le télécharger d'abord dans le système de fichiers:
.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
REMARQUE: ceci n'est généralement pas testé et peut nécessiter quelques modifications mineures pour obtenir la syntaxe exactement correcte. L'important ici est la méthode, pas une solution culte du copier-coller.
J'utilise des variantes de cette méthode (c'est-à-dire touch
un fichier d'horodatage) avec make
depuis des décennies. Cela fonctionne et me permet généralement d'éviter d'avoir à écrire mon propre code de résolution de dépendance dans sh (même si j'ai dû faire quelque chose de similaire avecstat --printf %Y
ici).
Tout le monde sait que make
c'est un excellent outil pour compiler des logiciels ... IMO c'est aussi un outil très sous-évalué pour les tâches d'administration système et de script.
-z
drapeau, bien sûr, suppose que le serveur distant utilise des en-If-Modified-Since
têtes. Ce n'est pas nécessairement le cas. Selon la configuration du serveur, vous devrez peut-être plutôt faire quelque chose avecETag
, ou en vérifiant les en-Cache-Control
têtes, ou en vérifiant un fichier de somme de contrôle distinct (par exemple, si le serveur fournit unsha1sum
).