¿Cómo puedo forzar la finalización de un bucle bash si se ejecuta x veces en x segundos?

¿Cómo puedo forzar la finalización de un bucle bash si se ejecuta x veces en x segundos?

Estoy intentando obtener lotes de entradas desde una tubería remota a través de ssh. Mi secuencia de comandos a continuación funciona bien, pero me gustaría agregarle algún tipo de verificación para que, si algo saliera mal o se rompiera, el ciclo terminara si la secuencia de comandos comenzara a ejecutarse.

¿Cómo puedo agregar un componente que verifique si el bucle se ejecutó, digamos 5 veces en 3 segundos, luego el script rompería el bucle y finalizaría automáticamente?

#!/bin/sh
if [ -z "$1" ]
    then
    echo " usage: user@host"
    echo
    exit
fi


while [ 1 ]
    do
    CB=`ssh $1 cat clipboardpipe`
    if [ -n "$CB" ]
        then
        echo $CB | /usr/bin/pbcopy
        echo $CB | /usr/local/bin/growlnotify
    fi
    sleep 1
done

PD: había considerado usar algo así tail -f, pero no parecía funcionar cuando otros programas esperan entradas en lotes. Todo consejo es bienvenido.

pss: clipboardpipees una canalización con nombre en el directorio de inicio del sistema remoto.

Respuesta1

GNU datetiene una precisión de nanosegundos a través de %N.

every=3     # test every n'th itteration 
bsecs=0.95  # break at secs (float)
bnano=$(printf '%0.9f' "$bsecs"); bnano=${bnano/./};  
# avoid lead '0' octal clash when time slice < 1 sec
shopt -s extglob; bnano=${bnano#+(0)}  

tprev=$(date +%s%N)
for i in {1..24} ;do  # just a test loop

  if ((i%every==1)) ;then
    tnow=$(date +%s%N)
    if ((tnow-tprev>=bnano)) ;then 
        echo "Auto Break!  $every itteratons took longer than $bsecs secs"
        break
    fi
    ((tprev=tnow))
  fi
  # do something, eg sleep for testing
  sleep 1.$i; echo $i
done

Respuesta2

Si estás en Linux, puedes usar else acabó el tiempocomando proporcionado por el paquete coreutils.

documentación de tiempo de espera

información relacionada