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 make
receita GNU primeiro verifica se example.gz
existe um arquivo chamado (porque vamos usá-lo com -z
in curl
) e o cria touch
se 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 curl
a opção 's -z
( --time-cond
) para fazer o download apenas example.gz
se tiver sido modificado desde a última vez em que foi baixado. -z
pode 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.dat
nã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.dat
deve existir para o próximo comando usar stat
para obter o registro de data e hora do mtime.
Então, se example.gz
tem um timestamp mais recente do que local.dat
, ele tubos example.gz
em transmogrify
e 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)
touch
es example.gz
para que ele tenha o mesmo timestamp quelocal.dat
O destino .PHONY garante que o local.dat
destino 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 transmogrify
sem 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 touch
um arquivo de carimbo de data / hora) make
há 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 %Y
aqui).
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.
-z
sinalização, é claro, assume que o servidor remoto usaIf-Modified-Since
cabeçalhos. Isso pode não ser necessariamente o caso. Dependendo da configuração do servidor, você pode precisar fazer algo comETag
, ou verificandoCache-Control
cabeçalhos ou verificando um arquivo de soma de verificação separado (por exemplo, se o servidor fornecer asha1sum
).