Restaurando o tty corretamente com stty

1

Estou escrevendo um script bash para ler alguma entrada do usuário (como uma solicitação de senha), e gostaria de capturar o resultado e passá-lo por sua stdout. (Estou trabalhando em um ambiente GNU / Linux, com software recente).

Aqui está uma versão simplificada do script que reproduz os problemas

....

# read_input.sh
#
# Issue B : redirection of "3>&1" here causes stty error when                                             
# this script is executed via a command subsitution context subshell                                                                       
exec 3>&1 </dev/tty >/dev/tty                                                                                     

tty_settings='stty -g'                                                                                            

# Issue A : uncommented version doesn't restore tty properly.                                                     
#trap 'stty "$tty_settings";' EXIT                                                                                
#trap 'echo "...interrupting"; exit 1' INT ABRT HUP QUIT TERM                                                     
trap 'echo "...interrupting"; stty "$tty_settings"; exit 1' INT ABRT HUP QUIT TERM                                

stty -echo                                                                                                        

echo "Enter input: "                                                                                              
input=""                                                                                                          
while IFS= read -r -n1 char; do                                                                                   
    # nb: stripped out proper char handling code here,                                                            
    # (except return), for simplicity                                                                             
    if [[ $char = "" ]]; then                                                                                     
        break
    fi
    input+=$char
    echo -n "*"
done
echo ""

stty "$tty_settings"

#trap - EXIT INT ABRT HUP QUIT TERM
trap - INT ABRT HUP QUIT TERM

echo "$input" >&3

A intenção é escrever para o fd 3 a entrada do resultado (se o stdout do script em invocação estiver conectado em um canal) - enquanto ainda estiver tendo tty durante a interação. Eu então modifico o tty com o stty para controlar o eco, etc, restaurando quaisquer modificações através do manuseio com o trap.

Eu encontrei dois problemas com isso.

Problema A

Na restauração do terminal de controle, o eco foi suprimido. Eu tive que usar o caso de manipulação de armadilha de duas linhas (comentado), em vez do caso do manipulador de uma linha ativa não comentada.

No caso de uma linha - digamos, no INT: o tty é restaurado, e a saída é chamada pelo manipulador. Eu não estou prendendo EXIT em si - por que isso seria necessário?

Problema B

Isso está relacionado ao redirecionamento "3 > & 1" do executivo em um contexto de subshell.

Por alguma razão, digamos que eu execute este script ("read_input.sh") em um subshell - e queira capturar sua saída de outro script por meio da substituição de comando:

....

# read_input_caller.sh
input=$(sh read_input.sh)
echo "$input"

Eu encontrei a invocação stty no manipulador de armadilha queixou-se do seguinte ao interromper o script de chamada (digamos com ^ C):

stty: 'standard input': Input/output error

Essa mensagem de erro só acontece por causa do redirecionamento "3 > & 1" na linha exec - chamando a linha exec sem "3 > & 1", não há nenhum erro stty (mas não muito útil para passar a entrada para stdout). Eu não posso pensar por que isso seria o caso?

No script de chamada, outra invocação de subshell como

....

sh read_input.sh | cat

Não produz este erro.

Curiosamente, quando o problema B ocorria, o terminal de controle parecia ser restaurado corretamente, mesmo sob a armadilha / restauração problemática do problema A.

    
por Stephen Brown 09.09.2017 / 19:06

0 respostas