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.