3 votes

bash rsync est tué par le signal 2

J'essaie d'empêcher l'utilisateur d'annuler le script en utilisant ctrl + c . Le script suivant s'exécute complètement, sauf que rsync qui insiste pour mourir, affichant l'erreur Killed by signal 2 .

Est-il possible d'éviter rsync de mourir ? Si oui, puis-je le mettre à l'arrière-plan, ou doit-il être au premier plan ?

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"

Je suspecte que le canal ssh meurt avant que rsync . Après la fin de la sortie de la strace dans le pid de rsync :

[...]
write(4, "\374\17\0\7", 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

1voto

nex3 Points 4309

Il est assez clair, d'après les expériences, que rsync se comporte comme d'autres outils tels que ping et n'héritent pas des signaux du parent Bash appelant.

Il faut donc être un peu créatif et faire quelque chose comme ce qui suit :

$ cat rsync.bash
#!/bin/sh

 set -m
 trap '' SIGINT SIGTERM EXIT
 rsync -avz LargeTestFile.500M root@host.mydom.com:/tmp/. &
 wait

 echo FIN

Maintenant, quand je le lance :

$ ./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

Et nous pouvons voir que le fichier a été entièrement transféré :

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

Comment cela fonctionne

L'astuce ici est que nous disons à Bash via set -m pour désactiver le contrôle des tâches sur toutes les tâches d'arrière-plan. Nous allons donc mettre en arrière-plan le rsync et ensuite exécuter un wait qui attendra la dernière commande d'exécution, rsync jusqu'à ce qu'il soit complet.

Nous gardons ensuite l'ensemble du script avec la balise trap '' SIGINT SIGTERM EXIT .

参考文献

0voto

PLG Points 133

Vous devez piéger le Ctrl + C pour la durée de l'exécution du 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

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X