Como lidar com backspace durante a leitura?

7

Como manejo os backspaces inseridos, mostra ^? se tentado & como read conta os caracteres, como em 12^?3 já foram completados 5 caracteres (embora todos eles não tenham sido inseridos de fato), mas depois de 12^?3^? ele retornou o prompt, estranho. Por favor ajude!

-bash-3.2$ read -n 5
12^?3^?-bash-3.2$
    
por Keyshov Borate 20.08.2014 / 07:46

3 respostas

8

Quando você lê uma linha inteira com read (ou read -r ou outras opções que não afetam esse comportamento), o editor de linha fornecido pelo kernel reconhece a tecla Backspace para apagar um caractere, bem como alguns outros comandos (incluindo Return para terminar a linha de entrada e enviá-la). As teclas de atalho podem ser configuradas com o stty . Diz-se que o terminal está no modo cozido quando seu editor de linhas está ativo. No modo raw, cada caractere digitado no teclado é transmitido para o aplicativo imediatamente. No modo cozido, os caracteres são armazenados em um buffer e somente linhas completas são transmitidas para o aplicativo.

Para interromper a leitura após um número fixo de caracteres, de forma a implementar read -n , o bash precisa alternar para o modo raw. No modo raw, o terminal não faz nenhum processamento da tecla Backspace (no momento em que você pressiona Backspace , o caractere anterior já foi enviado para o bash), e O bash também não faz nenhum processamento (presumivelmente porque isso dá a maior flexibilidade de permitir que o script faça seu próprio processamento).

Você pode passar a opção -e para habilitar o próprio editor de linhas do bash (readline, que é um editor de linhas apropriado, não como o extremamente bruto do kernel). Como o bash está fazendo a edição de linha, ele pode parar de ler uma vez que tenha o número de caracteres solicitado.

    
por 21.08.2014 / 01:45
7

Use read -e :

$ read -e -n 5
13acX

read -e significa que:

Readline (see Command Line Editing) is used to obtain the line.

Quando você faz isso, você pode editar a entrada de qualquer uma das maneiras que você faria ao escrever no prompt normal, incluindo backspace, Home , e assim por diante.

    
por 20.08.2014 / 07:54
1

read é um bash embutido. (veja type read .) Você pode encontrar documentação com man bash :

   read [-ers] [-a aname] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [-u fd] [name ...]
   [...]
          -e     If the standard input is coming from a terminal, readline (see READLINE above) is used to obtain the line.
                 Readline uses the current (or default, if line editing was not previously active) editing settings.

ou você pode usar help read :

read: read [-ers] [-a array] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [-u fd] [name ...]
      -e                use Readline to obtain the line in an interactive shell

A opção -e ativa o suporte readline, que basicamente permite todos os recursos disponíveis no prompt do shell, incluindo o tratamento de retrocesso.

Portanto, read -en 5 deve fazer o que você deseja.

    
por 20.08.2014 / 07:56