Existe um método de linha de comando pelo qual eu posso verificar se um arquivo baixado está completo ou quebrado?

13

Estou escrevendo um script que envolve o download e a manipulação de um arquivo, e quero garantir que o arquivo não esteja incompleto (devido, por exemplo, a uma queda de conexão) antes de trabalhar nele.

Clare
fonte

Respostas:

10

A maneira mais comum de verificar a integridade dos arquivos baixados é usar as somas de verificação MD5. Isso pressupõe que o site que você está baixando das somas de verificação MD5 realmente publicadas de seus arquivos. Você pode verificar uma soma de verificação MD5 criando sua própria soma de verificação do arquivo baixado e comparando-a com a soma de verificação publicada. Se eles forem idênticos, o arquivo que você baixou está completo e não violado.

Se você não espera que o arquivo que está baixando seja alterado, pode pré-compilar uma soma de verificação e codificá-la no script, mas se o arquivo for atualizado, a verificação falhará.

Para criar uma soma de verificação MD5 de uma execução de arquivo md5sum myFile. No caso do wget, você pode achar este comando útil, especialmente se o arquivo que você está baixando for grande:

wget -O - http://example.com/myFile | tee myFile | md5sum > MD5SUM.

Isso criará uma soma de verificação de "myFile" durante o download e a salvará no arquivo MD5SUM, possivelmente economizando algum tempo.

No caso de uma conexão interrompida, acho que a melhor maneira seria verificar os códigos de saída do wget. Se o download for bem-sucedido sem erros, o wget retornará 0. Qualquer outra coisa indica que algo deu errado. Dê uma olhada na seção "Status de saída" de man wget.

arnefm
fonte
2
códigos de saída: gnu.org/software/wget/manual/html_node/…
mikeserv
7

O código de retorno do comando usado para baixar o arquivo informará se o comando foi executado com êxito ou não. Normalmente, um código de retorno 0 indica sucesso e qualquer número diferente de zero indica um erro. Você pode acessar o código de retorno através da $?variável

Um exemplo básico usando wgetseria:

#!/bin/bash

wget foo.tgz &> /dev/null

if [[ "$?" != 0 ]]; then
    echo "Error downloading file"
else
    echo "Success"
fi

&> /dev/nullredireciona toda a saída do wget para, /dev/nullportanto, é ideal para scripts, mas torna os wgeterros de depuração mais difíceis.

Riacho
fonte
4
você pode fazer:wget -q ... || { handle ; error ; }
mikeserv
@mikeserv Nem sabia que estava lá, toque agradável
Creek
1
só o encontrei manenquanto lia a resposta e as duas coisas que eu ia dizer já estavam aqui em duas respostas - então eu fiz dois comentários. Toque agradável para você também.
precisa saber é o seguinte
Espero que isso não funcione quando usado com proxies do SOCKS como o tor.
#
1
@ Creek O que eu quis dizer é que wgetpode pensar que o download foi concluído, mesmo que ele quebrasse. Processa informações sobre conexões TCP quebradas versus conexões TCP fechadas, o que é problemático com o HTTP, pois ele usa TCP fechado como marca final por padrão. Foi por isso que adicionei uma verificação se o tamanho do arquivo do cabeçalho corresponde ao tamanho do arquivo baixado quando executei um download em massa. Não tenho certeza se wgetessa consistência verifica ou o que a especificação http diz sobre esse problema.
código é o seguinte