Tente algo assim no seu 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 é um Makefile, portanto, os recuos são tabulações, não espaços. é claro. Também é importante que não haja espaços após as \linhas de continuação - alternativamente, elimine as escapes da barra invertida e faça uma longa, linha quase ilegível)
Esta makereceita GNU primeiro verifica se example.gzexiste um arquivo chamado (porque vamos usá-lo com -zin curl) e o cria touchse não existir. O toque o cria com um registro de data e hora de 00:00 (00:00 do dia atual).
Em seguida, ele usa curla opção 's -z( --time-cond) para fazer o download apenas example.gzse tiver sido modificado desde a última vez em que foi baixado. -zpode receber uma expressão de data real ou um nome de arquivo. Se receber um nome de arquivo, ele usará a hora da modificação do arquivo como condição de hora.
Depois disso, se local.datnão existir, ele será criado touch, usando um carimbo de data / hora garantido para ser mais antigo que o de example.gz. Isso é necessário porque local.datdeve existir para o próximo comando usar statpara obter o registro de data e hora do mtime.
Então, se example.gztem um timestamp mais recente do que local.dat, ele tubos example.gzem transmogrifye redireciona a saída para local.dat.
Finalmente, ele faz as coisas de contabilidade e limpeza:
- trunca
example.gz(porque você só precisa manter um carimbo de data e hora, e não o arquivo inteiro)
touches example.gzpara que ele tenha o mesmo timestamp quelocal.dat
O destino .PHONY garante que o local.datdestino seja sempre executado, mesmo se o arquivo com esse nome já existir.
Agradeço a @Toby Speight por apontar nos comentários que minha versão original não funcionaria e por quê.
Como alternativa, se você quiser canalizar o arquivo diretamente transmogrifysem fazer o download primeiro no sistema de arquivos:
.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: como a maioria não é testada, pode ser necessário fazer pequenas alterações para obter a sintaxe exatamente correta. O importante aqui é o método, não uma solução de culto à carga de copiar e colar.
Eu tenho usado variações desse método (por exemplo, em touchum arquivo de carimbo de data / hora) makehá décadas. Funciona e geralmente me permite evitar escrever meu próprio código de resolução de dependência no sh (embora eu tenha tido que fazer algo semelhante stat --printf %Yaqui).
Todo mundo sabe que makeé uma ótima ferramenta para compilar software ... O IMO também é uma ferramenta muito subestimada para tarefas de administração e script do sistema.
-zsinalização, é claro, assume que o servidor remoto usaIf-Modified-Sincecabeçalhos. Isso pode não ser necessariamente o caso. Dependendo da configuração do servidor, você pode precisar fazer algo comETag, ou verificandoCache-Controlcabeçalhos ou verificando um arquivo de soma de verificação separado (por exemplo, se o servidor fornecer asha1sum).