Eu tenho um script como este (escrito para /bin/sh
no OpenBSD) que primeiro atualiza uma cópia local de alguns repositórios CVS usando rsync
, e então atualiza a versão com check-out destes no meu computador. O script é executado como root através do doas
do OpenBSD (a sudo
"equivalente" no OpenBSD):
#!/bin/sh
int_handler () {
echo 'Wait...' >&2
quit=1
}
quit=0
trap int_handler INT
for r in CVSROOT src xenocara ports; do
su cvsuser -c 'rsync --archive --itemize-changes --delete --omit-dir-times \
"rsync://anoncvs.eu.openbsd.org/OpenBSD-cvs/$r/" \
"/extra/cvs/$r/"'
done
trap - INT
[ "$quit" -eq 1 ] && exit
# rest of script updates checked-out CVS repositories from local copy
A idéia é que eu pressione Ctrl + C enquanto o loop rsync
está rodando para depois pular a segunda parte do script (que nem sempre quero executar, dependendo do que foi atualizado nos repositórios) sem interromper o loop e seus processos su
+ rsync
.
Isso não funciona e o processo rsync
recebe o sinal e termina (e a próxima iteração do loop for
continua). rsync
diz (quando pressiona Ctrl + C várias vezes até o script terminar):
^Crsync error: received SIGINT, SIGTERM, or SIGHUP (code 20) at rsync.c(642) [generator=3.1.3]
rsync error: received SIGINT, SIGTERM, or SIGHUP (code 20) at io.c(504) [receiver=3.1.3]
Wait...
rsync: [receiver] write error: Broken pipe (32)
rsync error: received SIGINT, SIGTERM, or SIGHUP (code 20) at io.c(1633) [sender=3.1.3]
^Crsync error: received SIGINT, SIGTERM, or SIGHUP (code 20) at rsync.c(642) [generator=3.1.3]rsync error: received SIGINT, SIGTERM, or SIGHUP (code 20) at io.c(504) [receiver=3.1.3
]
rsync: [receiver] write error: Broken pipe (32)
Wait...
^Crsync error: received SIGINT, SIGTERM, or SIGHUP (code 20) at rsync.c(642) [generator=3.1.3]
rsync error: received SIGUSR1 (code 19) at main.c(1440) [receiver=3.1.3]
Wait...
De acordo com uma resposta à pergunta " Como fazer ctrl + c / not / interromper o loop while? ", pelo menos quando executando bash
, deve-se ser capaz de ignorar o sinal INT
, o que fará com que os processos filhos também ignorem esse sinal. Isso não é ideal, mas eu ficaria feliz em tentar.
Então, segundo tente à luz disso:
#!/usr/local/bin/bash
trap '' INT
for r in CVSROOT src xenocara ports; do
su cvsuser -c 'rsync --archive --itemize-changes --delete --omit-dir-times \
"rsync://anoncvs.eu.openbsd.org/OpenBSD-cvs/$r/" \
"/extra/cvs/$r/"'
done
trap - INT
read -p 'Press enter or interrupt...' junk
# rest of script updates checked-out CVS repositories from local copy
Isso também permite que o processo rsync
seja interrompido por Ctrl + C .
Ok, então talvez seja o su
que redefine a máscara de sinal? Uma terceira tentativa:
#!/usr/local/bin/bash
trap '' INT
for r in CVSROOT src xenocara ports; do
su -s /usr/local/bin/bash cvsuser -c \
'trap "" INT; rsync --archive --itemize-changes --delete --omit-dir-times \
"rsync://anoncvs.eu.openbsd.org/OpenBSD-cvs/$r/" \
"/extra/cvs/$r/"'
done
trap - INT
read -p 'Press enter or interrupt...' junk
# rest of script updates checked-out CVS repositories from local copy
Não, não há alegria. O processo rsync
é ainda interrompível da mesma maneira.
Existe uma maneira de fazer o script funcionar da maneira que eu (inicialmente) pretendia?
bash
na minha máquina é o release 4.4.23. O /bin/sh
é a variante pdksh
nativa no OpenBSD rodando no modo POSIX.