Pruebe algo como esto en su 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: este es un Makefile, por lo que las sangrías son pestañas, no espacios. Por supuesto. También es importante que no haya espacios después \
de las líneas de continuación; alternativamente, elimine los escapes de barra invertida y hágalo uno largo, línea casi ilegible)
Esta make
receta de GNU primero verifica que example.gz
exista un archivo llamado (porque lo vamos a usar con -z
in curl
), y lo crea con touch
si no es así. El toque lo crea con una marca de tiempo de 00:00 (12am del día actual).
Luego usa curl
la opción 's -z
( --time-cond
) para descargar solo example.gz
si se ha modificado desde la última vez que se descargó. -z
se le puede dar una expresión de fecha real o un nombre de archivo. Si se le da un nombre de archivo, utilizará la hora de modificación del archivo como condición de tiempo.
Después de eso, si local.dat
no existe, lo crea con touch
una marca de tiempo que es más antigua que la de example.gz
. Esto es necesario porque local.dat
tiene que existir para que el siguiente comando lo use stat
para obtener su marca de tiempo mtime.
Entonces, si example.gz
tiene una marca de tiempo más reciente que local.dat
, tuberías de TI example.gz
en transmogrify
y redirige la salida a local.dat
.
Finalmente, hace las tareas de contabilidad y limpieza:
- se trunca
example.gz
(porque solo necesita mantener una marca de tiempo, y no todo el archivo)
touch
es example.gz
para que tenga la misma marca de tiempo quelocal.dat
El objetivo .PHONY asegura que el local.dat
objetivo siempre se ejecute, incluso si el archivo con ese nombre ya existe.
Gracias a @Toby Speight por señalar en los comentarios que mi versión original no funcionaría y por qué.
Alternativamente, si desea canalizar el archivo directamente transmogrify
sin descargarlo primero en el sistema de archivos:
.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: esto no se ha probado en su mayoría, por lo que puede requerir algunos cambios menores para obtener la sintaxis correcta Lo importante aquí es el método, no una solución de culto de carga de copiar y pegar.
He estado usando variaciones de este método (es decir, touch
marcando un archivo de marca de tiempo) make
durante décadas. Funciona, y generalmente me permite evitar tener que escribir mi propio código de resolución de dependencia en sh (aunque he tenido que hacer algo similar stat --printf %Y
aquí).
Todo el mundo sabe que make
es una gran herramienta para compilar software ... En mi opinión, también es una herramienta muy subestimada para las tareas de administración de scripts y administración del sistema.
-z
bandera, por supuesto, supone que el servidor remoto usaIf-Modified-Since
encabezados. Esto podría no ser necesariamente el caso. Dependiendo de la configuración del servidor, es posible que deba hacer algo conETag
, o al verificar losCache-Control
encabezados, o al verificar un archivo de suma de verificación por separado (por ejemplo, si el servidor proporciona unsha1sum
).