Bash Loop - Como parar o loop quando eu pressiono Control-C dentro de um comando?

32

Estou rsyncing alguns diretórios. Eu tenho um terminal bash aberto e estou executando algo assim:

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

No entanto, se eu quiser parar tudo, eu pressiono Control-C. Isso interrompe o rsync, mas continua indo para o próximo. Neste caso, eu percebo o que aconteceu e, em seguida, basta pressionar Control-C como um louco até que as coisas funcionem novamente.

Existe alguma maneira de "consertar" isso. Eu quero isso, então se eu tiver um loop como esse, e pressione Control-C, isso me retornará ao meu bash shell.

    
por Rory 22.01.2010 / 16:09

6 respostas

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

Isso também sairá do loop se uma execução individual do rsync falhar por algum motivo.

    
por 03.02.2010 / 20:03
23

Você pode definir um trap para o Control-C.

trap <command> SIGINT

executará o command quando o Control-C for pressionado. Basta colocar a declaração trap em algum lugar do seu script no ponto em que você deseja que ela se torne efetiva.

    
por 22.01.2010 / 16:16
21

Para expandir a resposta de Dennis, seu código pode se parecer com:

trap "echo Exited!; exit;" SIGINT SIGTERM

Para um exemplo de trabalho (que envolve o rsync), verifique o link .

    
por 16.07.2010 / 02:17
6

Quando você coloca uma string de comandos dentro de parênteses, a string irá atuar como um único processo, e receberá o SIGINT e terminará quando você pressionar Ctrl - C :

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

Mas! No caso do comando rsync , ele permite várias origens, portanto, o código que você escreveu seria melhor escrito como:

rsync -a * example.com:somewhere/
    
por 22.02.2011 / 05:06
5
  1. Pressione Ctrl-Z para suspender o script;
  2. kill %%

Créditos, explicações e mais detalhes em esta resposta .

    
por 03.08.2014 / 12:29
0

Eu costumo colocar outro comando no meu loop que pode ser facilmente interrompido. Requer que dois ctrl-C sejam pressionados.

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

Não é uma ótima solução para este rsync, que você provavelmente deseja executar rapidamente. Mas funciona bem para outros loops, como este:

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

Esse loop irá pesquisar novamente o endereço de example.com todas as vezes durante o loop, o que é útil se você estiver observando uma alteração de DNS.

    
por 04.03.2014 / 16:53