[sh] ¿Cómo puedo detectar si wget ha descargado bien un archivo? [Solucionado]
Publicado: 25 Diciembre, 2009 - 03:35 [sh] ¿Cómo puedo detectar si wget ha descargado bien un archivo? [Solucionado]
Cómo mi ISP me sigue puteando con las descargas he decidido mejorar mi cada-vez-más-recurrido-script:
#!/bin/bash
# macovallsucks, un script para cagarte en tu Proveedor de Servicios de Internet
# Lo escribí en emacs y sobreviví
#
matar()
{
kill -s SIGTERM $PID 2> /dev/null
exit
}
trap matar INT # Esto permite finalizar el script con Ctrl+C
while true ; do
wget -c $1 &
PID=$!
sleep 1m
kill -s SIGTERM $PID
done
Me he quedado pillado en cómo saber si el archivo terminó de descargar. wget se queda diciendo continuamente "El fichero ya ha sido totalmente recuperado, no hay nada que hacer.".
¿Ofrece wget alguna salida o algo que diga "sí, se ha descargado" que valga para un script?
- Inicie sesión o regístrese para enviar comentarios
- 867 lecturas


El manual de wget te puede ayudar:
man wgety, en concreto, echa un vistazo a la opción -nc
No tiene que ver. -nc simplemente no descarga si hay otro archivo con el mismo nombre.
El fundamento del script es que descargando pausando y reanudando la descarga cada 60 segundos para no perder la velocidad.
Buscando más información he encontrado esto: http://www.linuxquestions.org/questions/programming-9/gnu-wget-return-co...
Primero ejecuta wget y luego, de que ha terminado su ejecución consulta el valor de $?. Si es 0 se terminó de descargar.
El problema es que en mi script tengo que ejecutar wget en segundo plano para después matarlo, y $? no da el valor de retorno de wget si no el de algún otro comando.
¿Cómo puedo observar el valor de retorno de un proceso muerto que funcionaba en segundo plano?
Con wait, por ejemplo:
agluncomando &PID=$!
wait $PID
echo $? # muestra el returncode de alguncomando
La pega es que si el proceso no ha terminado cuando llamas a wait, éste se queda esperando a que termine, como si no lo hubieses puesto en segundo plano. Para determinar si el proceso ya terminó, puedes usar
jobs -pQue devuelve los PIDs de los procesos de fondo que se están ejecutando, como sólo tienes un proceso de fondo puedes hacer fácilmente un if, por ejemplo:
while truedo
algunproceso &
PID=$!
sleep 1m
if [ "$PID" == "$(jobs -p)" ]
then
# el proceso sigue activo, sólo hay que matarlo
kill -s SIGTERM $PID
else
# el proceso terminó, veamos su exitcode:
wait $PID
echo $?
# aquí creo que iría bien un break
fi
done
Ojo que ese código no lo he probado, sólo he comprobado el funcionamiento de los comandos wait y jobs y sus resultados.
No tiene que ver. -nc simplemente no descarga si hay otro archivo con el mismo nombre.
Cierto, la opción era -N. Copio literalmente del manual de wget:
When running Wget with -N, with or without -r or -p, the decision as to whether or not to download a newer copy of a file depends on the local and remote timestamp and size of the file.Es decir, llamando el script con -N ya no hará nada cuando el archivo esté descargado y tenga el tamaño del archivo a descargar. Supongo que se podrá combinar con -c.
Con wait, por ejemplo:
agluncomando &PID=$!
wait $PID
echo $? # muestra el returncode de alguncomando
La pega es que si el proceso no ha terminado cuando llamas a wait, éste se queda esperando a que termine, como si no lo hubieses puesto en segundo plano. Para determinar si el proceso ya terminó, puedes usar
jobs -pQue devuelve los PIDs de los procesos de fondo que se están ejecutando, como sólo tienes un proceso de fondo puedes hacer fácilmente un if, por ejemplo:
while truedo
algunproceso &
PID=$!
sleep 1m
if [ "$PID" == "$(jobs -p)" ]
then
# el proceso sigue activo, sólo hay que matarlo
kill -s SIGTERM $PID
else
# el proceso terminó, veamos su exitcode:
wait $PID
echo $?
# aquí creo que iría bien un break
fi
done
Ojo que ese código no lo he probado, sólo he comprobado el funcionamiento de los comandos wait y jobs y sus resultados.
Me sirvió de 10, gracias.
Ahora el script es una cosa tal que así:
#!/bin/bash# macovallsucks, un script para cagarte en tu Proveedor de Servicios de Internet
# Lo escribí en emacs y sobreviví
#
matar()
{
kill -s SIGTERM $PID 2> /dev/null
exit 1
}
trap matar INT # Esto permite finalizar el script con Ctrl+C
while true ; do
wget -c $1 &
PID=$!
sleep 1m
kill -s SIGTERM $PID 2> /dev/null
wait $PID
if [ $? -eq 0 ] # Descarga terminada
then
echo Descarga terminada
exit
else
echo Murió de "$?" puñaladas.
fi
done
Sigo trabajando en él, ahora quiero que si la descarga dura 20 segundos, no tenga que esperar a que pase el minuto para comprobar que wget ha finalizado.
Para no desviar el tema, marco este como solucionado y continuo en otro más acorde con el nuevo problema:
http://www.esdebian.org/foro/38008/sh-limpiar-script