Você pode tentar esse tipo de construção:
#!/bin/bash
#
INTR=
trap 'INTR=yes; echo "** INTR **" >&2' INT
while :
do
(
# Protect the subshell block
trap '' INT
# Protected code here
echo -n "The date/time is: "
sleep 2
date
read -t2 -p 'Continue (y/n)? ' YN || echo
test n = "$YN" && echo "Asked for BREAK" >&2 && exit 90
)
SS=$?
test 90 -eq $SS && echo "Matched BREAK" >&2 && break
# Ctrl/C, perhaps?
test yes = "$INTR" && echo "Matched INTR" >&2 && break
done
exit 0
Algumas notas
- O par
read
etest
demonstra o controle interativo para o segmento de código protegido dentro do bloco( ... )
. - O
exit 90
é o equivalente abreak
, mas dentro de um subshell. A linhatest 0 != $? ...
imediatamente após o subnível final termina para capturar o statusexit 90
e implementar obreak
que o código realmente queria. - O subshell pode usar diferentes valores de status de saída para indicar diferentes tipos de fluxo de controle necessário (
break
,exit
, etc ...) - Isso não impede que um programa instale seu próprio manipulador de sinal. Por exemplo,
gdb
instala seu próprio manipulador paraSIGINT
( Ctrl C ). Se o objetivo é evitar que um usuário saia da sessão, a alteração da chave de interrupção pode ajudar a ofuscar a situação (veja o código abaixo). Deselegante, mas potencialmente eficaz.
Alterando a tecla SIGINT no terminal
G=$(stty -g) # Save settings
test -n "$G" && stty intr ^A # That is caret and A, not Ctrl/A
# ... SIGINT generated with Ctrl/A rather than Ctrl/C ...
test -n "$G" && stty "$G" # Restore original settings