
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-Since
cabeçalho). Também preciso usar um nome personalizado para o arquivo no meu disco.
Que ferramenta posso usar para esta tarefa no Linux?
wget -N
não pode ser usado porque -N
não pode ser usado com -O
.
Responder1
Considere usar curl
em vez de wget
:
curl -o "$file" -z "$file" "$uri"
man curl
diz:
-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 $file
não necessariamente pré-existir, você precisará tornar o uso do -z
sinalizador 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 $zflag
aqui, 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 -N
só obtém o arquivo se ele tiver sido alterado, portanto, uma abordagem possível seria usar a -N
opçã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 -P
comando 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