Lendo a string de resposta do terminal em uma variável

2

Usando o bash , como posso ler o retorno do terminal em uma variável sem interação do usuário? O seguinte one-liner ainda requer que Enter seja pressionado uma vez:

echo -ne '
echo -ne '%pre%5' && read -s && echo ${REPLY}
5' && read -s && echo ${REPLY}

Além disso, como posso configurar o Xterm para enviar algo significativo em resposta a ^E ? Até agora, o único emulador de terminal que vi enviando qualquer resposta é o PuTTY .

    
por Bass 28.09.2016 / 18:38

2 respostas

5

A string de resposta de resposta é configurável no xterm usando o answerbackString recurso. Esse recurso foi adicionado em 1998 . Inicialmente retornando "xterm", uma vez que 1999 o padrão é uma string vazia, porque alguns usuários notaram o potencial por abuso de sequências de controle que podem enviar um comando inesperado ao computador.

Outros terminais podem retornar uma string vazia sempre (konsole, mlterm, vte). Mas rxvt (e rxvt-unicode) retornam uma resposta inesperada: o dispositivo atribui resposta para o VT102 (uma seqüência de escape). PuTTY retorna "PuTTY" (provavelmente devido à influência inicial do xterm ).

Em uma verificação rápida, o console do Linux exibe um "a" (provavelmente um bug).

Como o VT100 original fornecia isso como um recurso de configuração / configurável, isso seria limitado a caracteres imprimíveis . Por esse motivo, a resposta do rxvt / urxvt é inesperada. A página de manual faz um comentário obscuro sobre isso:

answerbackString: string
Specify the reply rxvt-unicode sends to the shell when an ENQ (control-E) character is passed through. It may contain escape values as described in the entry on keysym following.

(a descrição prometida está ausente).

Como o tamanho da string de resposta é desconhecido, um aplicativo que a lê deve permitir a espera (caso os caracteres cheguem em mais de uma operação de leitura). Existe, é claro, o recurso TMOUT específico do ksh / bash, que pode ajudar com o shell-scripting, junto com a opção -t para o comando read . Para uso geral, evito isso, usando stty , por exemplo, (consulte dynamic.sh ):

stty raw -echo min 0 time 5

para definir temporariamente o terminal para que read seja excedido em 0,5 segundos e permita que ele retorne sem ler nenhum caractere. Para ver como as configurações são salvas / restauradas, é útil ler o script.

Leitura adicional:

  • os scripts vttests em xterm , muitos dos quais lêem sequências de respostas de terminal .
  • stty - defina as opções para um terminal (POSIX)
  • read - leia uma linha da entrada padrão (POSIX)
por 28.09.2016 / 21:43
1

Mesmo com um tempo limite e um número de caracteres a serem lidos, aparece bash ( version 4.2.46(1)-release ) pode não salvar REPLY , emitindo a seqüência de controle "Report Cursor Position", primeiro com um nova linha inserida e segundo aguardando o tempo limite:

$ echo -ne '3[6n' && read -n 16 -s -t 3; echo -n $REPLY | xxd
0000000: 1b5b 3234 3b31 52                        .[24;1R
$ echo -ne '3[6n' && read -n 16 -s -t 3; echo -n $REPLY | xxd
$ 

O problema aqui é que -n é maior que o número de bytes retornados; se -n for exatamente o tamanho correto ou menor, a resposta será lida sem a necessidade de entrada (ou tempo limite). Se você conhece um caractere final exclusivo da string de resposta, pode obter uma resposta dividindo "linhas" por esse caractere; para o prompt de posição do caractere de relatório que o delimitador pode ser considerado como R :

$ echo -ne '3[6n' && read -n 999 -d R -s; echo -n $REPLY | xxd
0000000: 1b5b 3234 3b31                           .[24;1
$ 

Dada a entrada desconhecida de comprimento desconhecido, você teria que arquivar um bug contra bash ou talvez mordiscar os bytes um por um tedioso até que o tempo limite seja acionado:

$ out="got "; echo -ne '3[6n'; while read -n 1 -s -t 1; do out="$out$REPLY"; done
$ echo -n $out | xxd
0000000: 676f 7420 1b5b 3234 3b31 52              got .[24;1R
$ 

Para a coisa control + e , suponho que um terminal possa enviar algo de volta , mas teria que ser configurado para fazer isso:

ENQ       Return Terminal Status (Ctrl-E).  Default response is an empty
          string, but may be overridden by a resource answerbackString.
    
por 28.09.2016 / 19:52