Como lidar com NBSP em um terminal?
A seguir estão os comportamentos de eu colar exatamente a mesma string (que consiste em um NBSP principal) nos terminais:
$ echo abc
bash: echo: command not found
$ echo abc
abc
$ echo abc
-bash: $'\240echo': command not found
$ ls ~/.inputrc
ls: cannot access '/root/.inputrc': No such file or directory
$ ls ~/.bash*
/root/.bash_history /root/.bashrc
$ cat ~/.bashrc
. . . basically nothing there . . .
$ bind -v | grep bracketed
set enable-bracketed-paste on
$ lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description: Debian GNU/Linux bullseye/sid
Release: testing
Codename: bullseye
$ uname -rm
5.10.0-6-amd64 x86_64
O NBSP vem do documento que estou usando, seja LibreOffice Writer ou google doc etc. Então eu preciso muito fazer esse NBSP de colagem funcionar (como meu 2º caso), porque é onde eu documento meus comandos, ou seja, não consigo mudar seu comportamento.
Então,
- Para todos os três casos, não toquei em nenhuma configuração padrão do sistema ou na minha
- No meu segundo caso, o de trabalho, eu tenho
LANG=C
. Ambos os outros são baseados em utf8LANG
- No entanto, mesmo se eu mudar para
LANG=C
os outros dois, ainda estou recebendo o mesmo erro
O "método 1" desta resposta não funciona para mim:
e a bind '"\302\240":" "'
abordagem também não está funcionando para mim (esta é uma nova máquina com apenas root
usuário no momento, então o prompt pode parecer estranho):
Suponho que bind '"\302\240"
esteja associando a pressionar essa tecla no terminal, enquanto estou apenas colando. Apenas supondo.
$ echo $'\240echo abc' | grep -a $'\240'`
echo abc
nbsp=`echo $'\240'`
$ echo "${nbsp}echo abc${nbsp}${nbsp}${nbsp}def" | grep -a $'\240'
echo abc def
bind "${nbsp}":" "
# then paste in the above echo output,
$ od -c -
echo abc def
0000000 240 e c h o a b c 240 240 240 d e f \n
# paste again to bash, which will become:
$ echo abcdef
abcdef
# i.e., all the spaces have been eaten, instead of mapped as " "
$ tail -5 /etc/inputrc
# map NBSP to regular space (left part has NBSP in quotes, right part has space)
"\240":" "
"\302\240":" "
"Â ":" "
$ tail -4 /etc/inputrc | od -c -h
0000000 " \ 2 4 0 " : " " \n " \ 3 0 2
0000020 \ 2 4 0 " : " " \n " 302 240 " : "
0000040 " \n " 342 220 243 " : " " \n
Todos os comandos acima são feitos em xterm
, exceto o de tela preta, que é from urxvt
(que dá 302 240
od -c -
saída).
Conclusão:
Muito obrigado Kamil, por sua ajuda persistente. "É meia-noite onde eu moro" , disse ele, mas continuou "Vou verificar a pergunta em algumas horas" . São os comandos de ligação exatosbind 'set enable-bracketed-paste off'
, e essa é a última milha que eu preciso.
bind -r '\240'
bind '"\240":" "'
bind 'set enable-bracketed-paste on'
$ echo abc def
-bash: $'\240echo': command not found
bind 'set enable-bracketed-paste off'
$ echo abc def
abc def
Desculpe Kamil, devo ser mais cuidadoso seguindo o que você sugeriu.
Notas preliminares
\302\240
(em representação octal).\302\240
é para Unicode. Em iso8859-1 é único\240
(\xa0
, veja esta resposta ). Ajuste as soluções, se necessário.sed
ou qualquer outra coisa para corrigir o código no script.enable-bracketed-paste
foroff
(marquebind -v | grep bracketed
). A solução que substitui Enterfuncionará quando Enterfor digitada, mesmo queenable-bracketed-paste
sejaon
e o comando tenha sido colado.Solução global
A partir desta resposta no Ask Ubuntu:
E faz!
Readline deve entender
\302\240
. A versão a seguir não será quebrada por markdown, você pode copiá-la diretamente:Observe que esta solução pode afetar qualquer programa que use Readline e pode não haver uma maneira fácil de desabilitar a solução sob demanda para um programa. No Bash, você pode desativá-lo executando:
E reative por:
Instâncias separadas do Bash podem desabilitar a associação de forma independente.
Apenas para Bash
Se você deseja afetar o Bash, mas não outros programas que usam o Readline, coloque isso no seu
~/.bashrc
:Os comandos para desativar e reativar são exatamente como na solução anterior.
Dinamicamente
Esta função transformará todos os NBSPs na linha de comando em espaços regulares:
Vincule-o a alguma combinação não utilizada, por exemplo , Ctrl+ x, j:
Agora você pode limpar a linha de comando digitando Ctrl+ x, j.
Pode ser útil fazer com que o Bash faça isso automaticamente no Enter. Normalmente Enterenvia Ctrl+ m(verifique por Ctrl+ v, Enter, você deve ver
^M
), mas Ctrl+ jdeve funcionar também. Então vamos fazer Entersend Ctrl+ x, jpara acionar nossa função e depois Ctrl+ jpara executar o resultado:Ctrl+ jdigitado manualmente ainda permitirá que você execute a linha de comando sem chamar a função. Lembre-se de que a função transforma todos os NBSPs em espaços regulares. Se o seu código contiver NBSPs que devem sobreviver, você precisará corrigir outros NBSPs (ou seja, indesejados) manualmente e executar com Ctrl+ j.
Notas:
Para tornar a solução permanente, adicione a função e os
bind …
comandos ao seu arquivo~/.bashrc
.Se você optar por substituir Enter, a função será executada mesmo se Enterfor inserir uma nova linha após
\
ou dentro de uma string entre aspas (portanto, sem execução ainda). Isso não deve quebrar as coisas, desde que você queira que os NBSPs sejam convertidos. Ainda executar a função várias vezes quando a execução final sozinha faria todo o trabalho é deselegante. Por outro lado, a função não chama utilitários externos comosed
, ela faz seu trabalho totalmente dentro do Bash, então mesmo chamá-la várias vezes em vão de vez em quando não é tão ruim.Mas se você colar um comando de várias linhas onde os NBSPs devem sobreviver (portanto, você usará Ctrl+ jcomo recomendado acima), os caracteres de nova linha sendo colados acionarão a função para fragmentos já colados. Para corrigir isso, investigue a pasta entre colchetes .