baixe o arquivo via http somente se alterado desde a última atualização

baixe o arquivo via http somente se alterado desde a última atualização

Preciso baixar um arquivo de um servidor HTTP, mas somente se ele mudou desde a última vez que baixei (por exemplo, através do If-Modified-Sincecabeçalho). Também preciso usar um nome personalizado para o arquivo no meu disco.

Que ferramenta posso usar para esta tarefa no Linux?


wget -Nnão pode ser usado porque -Nnão pode ser usado com -O.

Responder1

Considere usar curlem vez de wget:

curl -o "$file" -z "$file" "$uri"

man curldiz:

-z/--time-cond <expressão de data>

(HTTP/FTP) Solicite um arquivo que tenha sido modificado depois da hora e data especificadas ou que tenha sido modificado antes dessa hora. A expressão de data pode ser todos os tipos de strings de data ou, se não corresponder a nenhuma string interna, ela tenta obter a hora de um determinado nome de arquivo.

Se $filenão necessariamente pré-existir, você precisará tornar o uso do -zsinalizador condicional, usando test -e "$file":

if test -e "$file"
then zflag="-z '$file'"
else zflag=
fi
curl -o "$file" $zflag "$uri"

(Observe que não citamos a expansão $zflagaqui, pois queremos que ela seja dividida em 0 ou 2 tokens).

Se o seu shell suporta arrays (por exemplo, Bash), então temos uma versão mais segura e limpa:

if test -e "$file"
then zflag=(-z "$file")
else zflag=()
fi
curl -o "$file" "${zflag[@]}" "$uri"

Responder2

A opção wget -Nsó obtém o arquivo se ele tiver sido alterado, portanto, uma abordagem possível seria usar a -Nopção simples que obterá o arquivo se necessário, mas o deixará com o nome errado. Em seguida, crie um link físico usando o ln -Pcomando para vinculá-lo a um “arquivo” com o nome correto. O arquivo vinculado possui os mesmos metadados do original.

A única limitação é que você não pode ter links físicos entre os limites do sistema de arquivos.

Responder3

Script Python 3.5+ para agrupar o comando curl:

import argparse
import pathlib

from subprocess import run
from itertools import chain

parser = argparse.ArgumentParser()
parser.add_argument('url')
parser.add_argument('filename', type=pathlib.Path)
args = parser.parse_args()

run(chain(
    ('curl', '-s', args.url),
    ('-o', str(args.filename)),
    ('-z', str(args.filename)) if args.filename.exists() else (),
))

Responder4

Eu tentei várias coisas com o wget e não consegui impedir que ele truncasse a saída, a menos que usasse " -N ".

Em vez disso, você pode preparar seu próprio cabeçalho -if-modificado e substituir arquivos truncados por backups.

OUTFILE="some.thing"
IF_MOD_DATE=`date "+%a, %d %b %Y %T %Z" -r $OUTFILE`
IF_MOD_HEADER="If-Modified-Since: $IF_MOD_DATE"

cp $OUTFILE backup_$OUTFILE
wget -O $OUTFILE --header="$IF_MOD_HEADER" "http://your.tld/resource"

# if files is truncated, replace with backup
[ -s $OUTFILE ] || { rm $OUTFILE && mv backup_$OUTFILE $OUTFILE ; }

# remove any backup and ignore complaints of missing files.
rm backup_$OUTFILE 2>&1

informação relacionada