Digamos que um aplicativo estava solicitando a entrada do teclado e eu mantive uma tecla pressionada por um tempo.
Agora, o aplicativo está respondendo às teclas pressionadas, mas fica mais lento à medida que avança.
A idéia é limpar todos esses pressionamentos de tecla recebidos, armazenados em algum lugar em um buffer, para que o aplicativo pare o que está fazendo mal.
Você deve indicar qual tipo de aplicação: terminal (POSIX syscall, curses, ou stdio API), Qt, Gtk…
Se for um terminal (syscall) você pode usar o
select
syscall e verificar se algo está disponível na entrada padrão, e enquanto for verdadeiro, leia.É mais uma questão de programação.
Vou responder à pergunta do título
How to clear the keyboard buffer?
no sentido de que tudo o que foi digitado até agora e é percebido como uma entrada que está esperando que um programa o consuma, será limpo, e aqui está como faço isso em um arquivo executável ( ou seja.chmod a+x clrbuf
) chamadoclrbuf
que consome silenciosamente a entrada:Explicação:
tl;dr: consome silenciosamente todas as entradas e, se não houver entrada, apenas saia após 0,1 segundos (100ms), use
stty
para garantir queread
não desabilitou o eco do que o usuário digita, o que pode acontecer em determinados casos.Isso está usando o
read
comando interno /bin/bash (ou seja, tente$ help read
enquanto estiver nobash
shell, ou veja este documento ) e usando /bin/stty que é parte do pacote coreutils (no Gentoo).Ele vai ler tudo o que está esperando para ser lido e ignorá-lo.
Por exemplo, se você executar
sleep 5 ; clrbuf
, começará a digitar algo como ahello
tecla +enter e parar de digitar, depois de 5 segundosclrbuf
será executado e consumirá o que você digitou, para que o prompt do terminal não receba essa entrada. Assim:Os argumentos para
read
:O
--
não é necessário, marca o fim de todos os argumentos, é apenas um hábito para mim.pois lá está esperando um identificador de variável onde colocar o resultado da leitura.
-r
"não permita que as barras invertidas escapem de nenhum caractere. A barra invertida não atua como um caractere de escape. A barra invertida é considerada parte da linha. Em particular, um par barra invertida-nova linha não pode ser usado como uma continuação de linha." (dehelp read
e desse documento )-t TIMEOUT
"Fazer com que a leitura expire e retorne a falha se uma linha completa de entrada não for lida dentro de TIMEOUT segundos. Esta opção não tem efeito se a leitura não estiver lendo a entrada do terminal ou de um pipe." ( do mesmo documento ).-t 0.1
é usado para sair automaticamenteread
após 0,1 segundo quando não há entrada pendente para ser consumida.-s
"Modo silencioso. Se a entrada estiver vindo de um terminal, os caracteres não serão ecoados."( do mesmo documento )Por exemplo, se eu digitar "hi"+enter, uma vez:
-e
"readline é usado para obter a linha". Por alguma razão, notei que não funciona sem esse argumento. Não me lembro por que, mas observei que é verdade para "GNU bash, versão 5.0.16(1)-maint (x86_64-pc-linux-gnu) commit 3235014e5b3d227ccd617b0be72d897eb476d23d na ramificação devel Data: Seg 20 de abril 10:11:53 2020 -0400". Para o que vale a pena, eu compilei o bash no Gentoo com USE=bundled-readline e talvez seja por isso que ainda funcione sem-e
para mim atualmente. Eu não tenho certeza.exit 0
é sempre certificar-se de retornar o sucesso do script, apenas no caso declrbuf
ser usado em outro script bash que tenhaset -e
(o que faria com que esse script saísse se um código de saída diferente de 0 acontecesse após chamar oclrbuf
script) (" -e Exit imediatamente se um comando sair com um status diferente de zero. "). Exemplo:Por que é
stty echo echok
necessário?Devido a
read -s
(também conhecido como silencioso) que faz o equivalente astty -echo -echok
(ou seja, desativarecho
eechok
), para garantir que o usuário nunca fique sem a capacidade de ecoar o que é digitado, em alguns casos, garantimos que o eco é ativado depois deread -s
concluído.O exemplo a seguir (c.bash) ilustra quando isso pode acontecer:
A saída é esta:
Como você pode ver no final
-echo -echok
, há coisas novas que são definidas (para desabilitadas), em comparação com antes de chamarread -s ... &
quando elas foram habilitadas (e, portanto, não impressas por stty). E a última linhastty echo echok
irá certificar-se de habilitá-los (observe que eles não têm o-
prefixo menos ( ), caso contrário você não verá o que você digita no prompt de comando (ou seja, o eco do que você digita está desabilitado) depois disso script sai.Observe que este exemplo não é a única maneira de entrar nesse estado, mas é um exemplo que me ajudou a reproduzir o problema de ter o eco desabilitado quando eu estava usando apenas
read
toclrbuf
, semstty
.Uma maneira melhor pode ser salvar o estado do
echo
eechok
antes que oread -s ...
seja invocado e, em seguida, restaurar os estados posteriormente. Mas isso é propenso a condições de corrida (se o programa que desativou os ecos os reativa durante nossoread -s
, em paralelo) e, portanto, corre o risco de deixar o usuário com o terminal unecoable (quando osstty
restaura como desativados). Pessoalmente, eu não arriscaria implementar essa variante.