bash rsync é morto por sinal 2

4

Estou tentando impedir que o usuário cancele o script usando ctrl + c . O script a seguir é executado completamente, exceto rsync que insiste em morrer, exibindo o erro Killed by signal 2 .

É possível evitar que rsync morra? Em caso afirmativo, posso colocá-lo em segundo plano ou em primeiro plano?

script:

trap '' SIGINT SIGTERM SIGQUIT

cd /tmp
nohup rsync  -e 'ssh -o LogLevel=ERROR' -av --timeout=10 --delete-excluded myapp.war myserver:/tmp/  < /dev/null > /tmp/teste 2> /tmp/teste2

let index=0
while [ $index -lt 400000 ]
do
  let index=index+1
done

echo "script finished"
echo "index:$index"

Estou suspeitando que o canal ssh está morrendo antes de rsync . Após o final da saída do comando strace no pid de rsync :

[...]
write(4, "4
trap '' SIGINT SIGTERM SIGQUIT

cd /tmp
nohup rsync  -e 'ssh -o LogLevel=ERROR' -av --timeout=10 --delete-excluded myapp.war myserver:/tmp/  < /dev/null > /tmp/teste 2> /tmp/teste2

let index=0
while [ $index -lt 400000 ]
do
  let index=index+1
done

echo "script finished"
echo "index:$index"
", 4) = 4 select(5, NULL, [4], [4], {10, 0}) = 1 (out [4], left {9, 999998}) --- SIGINT (Interrupt) @ 0 (0) --- --- SIGCHLD (Child exited) @ 0 (0) --- wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 255}], WNOHANG, NULL) = 12738 wait4(-1, 0x7fffaea6a85c, WNOHANG, NULL) = -1 ECHILD (No child processes) rt_sigreturn(0xffffffffffffffff) = 0 select(0, NULL, NULL, NULL, {0, 400000}) = 0 (Timeout) rt_sigaction(SIGUSR1, {SIG_IGN, [], SA_RESTORER, 0x3fcb6326b0}, NULL, 8) = 0 rt_sigaction(SIGUSR2, {SIG_IGN, [], SA_RESTORER, 0x3fcb6326b0}, NULL, 8) = 0 wait4(12738, 0x7fffaea6aa7c, WNOHANG, NULL) = -1 ECHILD (No child processes) getpid() = 12737 kill(12738, SIGUSR1) = -1 ESRCH (No such process) write(2, "rsync error: unexplained error ("..., 72) = 72 write(2, "\n", 1) = 1 exit_group(255) = ? Process 12737 detached
    
por Francisco 16.07.2015 / 15:42

2 respostas

1

É bem claro pela experimentação que rsync se comporta como outras ferramentas como ping e não herda sinais do pai Bash chamador.

Então você tem que ter um pouco de criatividade com isso e fazer algo como o seguinte:

$ cat rsync.bash
#!/bin/sh

 set -m
 trap '' SIGINT SIGTERM EXIT
 rsync -avz LargeTestFile.500M [email protected]:/tmp/. &
 wait

 echo FIN

Agora, quando eu executo:

$ ./rsync.bash
X11 forwarding request failed
building file list ... done
LargeTestFile.500M
^C^C^C^C^C^C^C^C^C^C
sent 509984 bytes  received 42 bytes  92732.00 bytes/sec
total size is 524288000  speedup is 1027.96
FIN

E podemos ver que o arquivo foi totalmente transferido:

$ ll -h | grep Large
-rw-------. 1  501 games 500M Jul  9 21:44 LargeTestFile.500M

Como funciona

O truque aqui é que estamos informando ao Bash via set -m para desativar os controles de trabalho em quaisquer trabalhos em segundo plano dentro dele. Em seguida, estamos fazendo o background rsync e, em seguida, executando o comando wait , que aguardará no último comando de execução, rsync , até que esteja concluído.

Em seguida, guardamos todo o script com o trap '' SIGINT SIGTERM EXIT .

Referências

por 10.07.2018 / 03:50
0

Você precisa capturar a Ctrl + C durante a execução do script.

#!/bin/bash

trap ctrl_c INT

function ctrl_c() {
        echo "Oops CTRL-C not allowed!"
}

for i in 'seq 1 5';
do
    echo "doing something... blah blah blah... try pressing Ctrl+C"
    sleep 1
done
    
por 16.07.2015 / 16:30

Tags