¿Existe un método de línea de comando por el cual puedo verificar si un archivo descargado está completo o roto?

13

Estoy escribiendo una secuencia de comandos que implica descargar y manipular un archivo, y quiero asegurarme de que el archivo no esté incompleto (debido, por ejemplo, a una conexión caída) antes de trabajar en él.

Clara
fuente

Respuestas:

10

La forma más común de verificar la integridad de los archivos descargados es usar sumas de verificación MD5. Esto supone que el sitio que está descargando desde las sumas de verificación MD5 publicadas de sus archivos. Puede verificar una suma de verificación MD5 creando su propia suma de verificación del archivo descargado y comparándola con la suma de verificación publicada. Si son idénticos, el archivo que ha descargado está completo y no se ha alterado.

Si no espera que cambie el archivo que está descargando, puede calcular previamente una suma de verificación y codificarlo en el script, pero si el archivo se actualiza alguna vez, la verificación fallará.

Para crear una suma de comprobación MD5 de un archivo ejecutado md5sum myFile. En el caso de wget, puede encontrar útil este comando, especialmente si el archivo que está descargando es grande:

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

Esto creará una suma de comprobación de "myFile" durante la descarga y la guardará en el archivo MD5SUM, posiblemente ahorrándole algo de tiempo.

En el caso de una conexión caída, creo que la mejor manera sería verificar los códigos de salida de wget. Si la descarga se realiza sin errores, wget volverá 0. Cualquier otra cosa indica que algo salió mal. Consulte la sección "Estado de salida" de man wget.

arnefm
fuente
2
códigos de salida: gnu.org/software/wget/manual/html_node/…
mikeserv
7

El código de retorno del comando utilizado para descargar el archivo le indicará si el comando se ejecutó correctamente o no. Por lo general, un código de retorno de 0 indica éxito y cualquier número distinto de cero denota un error. Puede acceder al código de retorno a través de la $?variable.

Un ejemplo básico usando wgetsería:

#!/bin/bash

wget foo.tgz &> /dev/null

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

&> /dev/nullredirige toda la salida de wget, por /dev/nulllo que es ideal para la creación de scripts, pero hace que los wgeterrores de depuración sean más difíciles.

Arroyo
fuente
44
puede hacer en su lugar:wget -q ... || { handle ; error ; }
mikeserv
@mikeserv Ni siquiera sabía que estaba allí, buen toque
Creek
1
solo lo encontré manmientras leía para responder y las dos cosas que iba a decir ya estaban aquí en dos respuestas, así que hice dos comentarios. Buen toque para ti también.
mikeserv
Espero que esto no funcione cuando se usa con servidores proxy SOCKS como tor.
CodesInChaos
1
@Creek Lo que quise decir es que wgetpodría pensar que la descarga se completó, incluso si se rompió. Información de proxy sobre conexiones TCP rotas frente a conexiones TCP cerradas, lo cual es problemático con HTTP, ya que utiliza TCP cerrado como marca final de forma predeterminada. Es por eso que agregué un cheque si el tamaño del archivo del encabezado coincide con el tamaño del archivo descargado cuando ejecuté una descarga masiva. No estoy seguro de si se wgetverifica dicha coherencia o lo que dice la especificación http sobre este tema.
CodesInChaos