Bash Loop: ¿cómo detener el ciclo cuando presiono Control-C dentro de un comando?


35

Estoy sincronizando algunos directorios. Tengo una terminal de bash abierta y estoy ejecutando algo como esto:

for DIR in * ; do rsync -a $DIR example.com:somewhere/ ; done

Sin embargo, si quiero detener todo, presiono Control-C. Eso detiene el rsync, pero luego continúa con el siguiente. En este caso, me doy cuenta de lo que sucedió y luego presiono Control-C como un loco hasta que las cosas funcionen nuevamente.

¿Hay alguna manera de "arreglar" esto? Lo quiero, así que si tengo un bucle como ese, y presiono Control-C, me devolverá a mi shell bash.


66
La respuesta de Dennis es la correcta, pero si no lo hiciste, no tienes que 'presionarlo como un loco', solo sosténlo y deja que el teclado lo repita :-)
Kyle Brandt

Siempre mantengo presionado Cntl-C, generalmente funciona bien.
Scott Alan Miller

Respuestas:


33
for DIR in * ; do rsync -a $DIR example.com:somewhere/ || break; done

Esto también saldrá del ciclo si una ejecución individual de rsync falla por alguna razón.


44
Sugerencia adicional: si está en un bucle anidado y desea terminar por completo, use break 2(o reemplace "2" con el número de bucles anidados que desea terminar).
Dolan Antenucci el

26

Para ampliar la respuesta de Dennis, su código podría verse así:

trap "echo Exited!; exit;" SIGINT SIGTERM

Para ver un ejemplo de trabajo (que involucra rsync), consulte http://gist.github.com/279849 .


Gracias, esta es una solución genérica que funcionó para mí
wi1

25

Puede establecer una trampa para Control-C.

trap <command> SIGINT

ejecutará commandcuando se presione Control-C. Simplemente coloque la trapdeclaración en algún lugar de su secuencia de comandos en un punto donde desee que se haga efectiva.



6

Cuando coloca una cadena de comandos entre paréntesis, la cadena actuará como un solo proceso, y recibirá el SIGINT y terminará cuando presione Ctrl- C:

(for DIR in * ; do rsync -a $DIR example.com:somewhere/ ; done)

¡Pero! En el caso del rsynccomando, permite múltiples fuentes, por lo que el código que escribió se escribiría mejor como:

rsync -a * example.com:somewhere/

0

Tiendo a poner otro comando en mi bucle que se puede interrumpir fácilmente. Requiere presionar dos ctrl-C's.

for DIR in * ; do rsync -a $DIR example.com:somewhere/ ; sleep 1 ; done

No es una gran solución para este rsync, que probablemente quieras ejecutar rápidamente. Pero funciona bien para otros bucles, como este:

while true ; do ping -c 10 example.com ; sleep 1 ; done

Este bucle volverá a buscar la dirección de example.com cada vez a través del bucle, lo cual es útil si está buscando un cambio de DNS.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.