Como lidar com backspace durante a leitura?

10

Como faço para lidar com os backspaces inseridos, ele mostra ^?se tentou e como readconta os caracteres, 12^?3já que 5 caracteres estavam completos (embora nem todos tenham sido reais), mas depois que 12^?3^?ele retornou o prompt, estranho. Por favor ajude!

-bash-3.2$ read -n 5
12^?3^?-bash-3.2$
Keyshov Borate
fonte

Respostas:

10

Quando você lê uma linha inteira com opções simples read(ou read -routras opções que não afetam esse comportamento), o editor de linhas fornecido pelo kernel reconhece a Backspacechave para apagar um caractere, além de alguns outros comandos (inclusive Returnpara concluir a entrada linha e envie). As teclas de atalho podem ser configuradas com o sttyutilitário. Diz-se que o terminal está no modo cozido quando o editor de linha está ativo. No modo bruto, cada caractere digitado no teclado é transmitido ao aplicativo imediatamente. No modo cozido, os caracteres são armazenados em um buffer e somente linhas completas são transmitidas ao aplicativo.

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

Você pode passar a opção -ede ativar o editor de linhas do bash (readline, que é um editor de linhas adequado, não como o extremamente bruto do kernel). Como o bash está executando a edição de linha, ele pode parar de ler quando tiver o número solicitado de caracteres.

Gilles 'SO- parar de ser mau'
fonte
9

Use read -e:

$ read -e -n 5
13acX

read -e significa que:

O Readline (consulte Edição da linha de comando ) é usado para obter a linha.

Ao fazer isso, você pode editar a entrada de qualquer maneira que faria ao escrever no prompt normal do shell, incluindo backspace Homee assim por diante.

Michael Homer
fonte
1

readé um bash embutido. (consulte type read.) Você pode encontrar documentação em 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

O -eswitch habilita o suporte à linha de leitura, que basicamente permite todos os recursos disponíveis no prompt do shell, incluindo manipulação de backspace.

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

michas
fonte
-e resolve o problema, mas como a readleitura do 'número de caracteres digitados' ainda não foi respondida.
precisa saber é o seguinte