Cómo repetir el bucle n veces en Bash

9

Tengo el siguiente escenario como:

if [file exists]; then
   exit   
elif
   recheck if file exist (max 10 times)
   if found exit else recheck again as per counter  
fi 
Rocky86
fuente
Esta es una característica muy básica en los depósitos. ¿Incluso lo investigaste?
Peschke
Si. Pero no obtengo el resultado esperado de mi código. También quiero escribir lo más abreviado posible
Rocky86
1
@Peschke, bueno, necesitarían al menos qué, tres características básicas (bucles, condicionales, probar el archivo, salir de un bucle). Al menos la pregunta es bastante clara. Aunque podría contener un bosquejo de lo que Rocky intentó, de todos modos alguien lo reescribiría en las respuestas. ;)
ilkkachu

Respuestas:

9

Hay muchas formas de hacer este ciclo.

Con ksh93sintaxis (también compatible con zshy bash):

for (( i=0; i<10; ++i)); do
    [ -e filename ] && break
    sleep 10
done

Para cualquier shell similar a POSIX:

n=0
while [ "$n" -lt 10 ] && [ ! -e filename ]; do
    n=$(( n + 1 ))
    sleep 10
done

Ambos bucles duermen 10 segundos en cada iteración antes de probar nuevamente la existencia del archivo.

Después de que el ciclo haya finalizado, tendrá que probar la existencia del archivo por última vez para determinar si el ciclo se cerró debido a que se ejecutó 10 veces o debido a la aparición del archivo.

Si lo desea, y si tiene acceso a las herramientas de inotify, puede reemplazar la sleep 10llamada con

inotifywait -q -t 10 -e create ./ >/dev/null

Esto esperaría a que ocurra un evento de creación de archivo en el directorio actual, pero se agotaría el tiempo de espera después de 10 segundos. De esta manera, su bucle se cerrará tan pronto como aparezca el nombre de archivo dado (si apareciera).

El código completo, con inotifywait(reemplace con sleep 10si no quiere eso), puede verse como

for (( i=0; i<10; ++i)); do
    [ -e filename ] && break
    inotifywait -q -t 10 -e create ./ >/dev/null
done

if [ -e filename ]; then
    echo 'file appeared!'
else
    echo 'file did not turn up in time'
fi
Kusalananda
fuente
Con inotify, casi podría reemplazar todo el ciclo. Simplemente pruebe si el archivo está allí y, si no, inotifywait durante 100 segundos. Casi, ya que el archivo se podría crear simplemente entre la prueba y la inotify, y que le dormir para el total de 100 segundos antes de que se agote el tiempo ...
ilkkachu
1
@ilkkachu Sí, es una buena idea, pero aquí solo la estoy usando inotifywaitcomo reemplazo directo sleep.
Kusalananda
8

Si el recuento no es una variable, puede usar la expansión de llaves:

for i in {1..10}   # you can also use {0..9}
do
  whatever
done

Si el recuento es una variable, puede usar el seqcomando:

count=10
for i in $(seq $count)
do
  whatever
done
xenoide
fuente
Quiero hacer un bucle solo si no se encuentra el archivo (máx. 10 veces). Si se encuentra, digamos la tercera vez, salga con éxito
Rocky86
@ Rocky86: Esto no contradice la solución propuesta por xenoid. Nadie te obliga a contar hasta el final ...
user1934428
Me gusta este$(seq $count)
Trabajador
0
n=0
until [ "$((n+=1))" -gt 10 ]
do    <exists? command exit
done
echo oh noes!

aunque test -e file && exites más flexible

mikeserv
fuente
¿Por qué el signo de interrogación? Tenga en cuenta que el comportamiento de los globos en el objetivo de las redirecciones varía entre los depósitos.
Stéphane Chazelas
2
Tenga en cuenta que tiene el efecto secundario de abrir el archivo, que, por ejemplo, para los quince puede ser bastante malo (peor con un enlace simbólico a / dev / watchdog en Linux, por ejemplo)
Stéphane Chazelas
Incluso en Bash, donde esto buscaría un archivo como exists1o similar , todavía imprime un montón de errores si / cuando no se encuentra un archivo coincidente. (También se produce un error si hay varias coincidencias.) Cualquier otro shell que probé parece dar errores en cualquier caso ...
ilkkachu
@ikkachu: sí. ese era un poco el punto. Si ocurre el error, el script informa. Si se debe suprimir stderr, suprímalo done 2<>/dev/null. hace basheso guionizado? Pensé que solo se -idesvanecía en un contexto interactivo. aún así, exists?es tanto como un nombre de relleno como file. Pero sí, odio citando en redirecciones - si los tornillos de manera mucho más arriba.
mikeserv
@ Stéphane, no hay razón, de verdad. pero sí, fifos, ilegibles ... por eso lo noté test -e.
mikeserv