[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?

El manual de wget te puede ayudar:

man wget

y, 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 -p

Que 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 true
do
  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.

warcry escribió:

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.

DeJhanX escribió:

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 -p

Que 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 true
do
  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