Como inserir caracteres especiais para que o Bash / Terminal os entenda?

18

Digamos que uma pasta tenha um arquivo chamado Näyttökuva.png(para quem estiver interessado, é uma “captura de tela” em finlandês). Isto é o que acontece:

$ ls
Näyttökuva.png

$ ls N*
Näyttökuva.png

$ ls Nä*
ls: Nä*: No such file or directory

Isso também afeta a conclusão automática da guia. Se eu começar a digitar ls Ne pressionar, tabele será expandido corretamente para ls Näyttökuva.png. Mas se eu começar a digitar ls Nätabulação não faz nada.

Como posso:

  • configure o bash / terminal para entender caracteres especiais
  • digite os caracteres especiais para que o bash / terminal os entenda?

No Terminal, a codificação é definida como UTF-8 na guia Configurações e a guia Codificação está no seu estado padrão, ou seja. UTF-8, Mac OS Roman, ISO Latin 1, ISO Latin 9, Windows Latin 1, ASCII, NextStep + algumas codificações asiáticas estão ativadas.


Ainda mais estranho (embora provavelmente não seja essencial para a pergunta):

Se eu digitar ls N, pressionar tab, excluir caracteres do final até que ele seja lido ls Näe pressionar tabnovamente, o comando será expandido para ls Nättökuva.png[sic].

Se eu tentar excluir as letras pela segunda vez ls Näe pressionar a tecla tab, ela será expandida para ls Nätökuva.png. A terceira execução se expande para ls Näökuva.png.

Por alguma razão, a quarta corrida dá ls Nä̈kuva.png(observe os treinos sobre treinos). Tabular o ls Nä̈ls Nä̈kuva.pngsempre. No entanto, funciona:

$ ls Nä̈kuva.png
Näyttökuva.png

$ history 2
518  ls Näyttökuva.png 
519  history 2
Jari Keinänen
fonte

Respostas:

23

Eu acho que o bash está tropeçando em algumas anomalias na maneira como os caracteres acentuados são tratados. Você pode pegar um pouco de pipoca, porque isso será técnico por um tempo ...

O Unicode permite que alguns caracteres acentuados sejam representados de várias maneiras diferentes: como um "ponto de código" representando o caractere acentuado ou como uma série de pontos de código representando a versão não acentuada do caractere, seguida pelo (s) acento (s). Por exemplo, "ä" pode ser representado pré-composto como U + 00E4 (UTF-8 0xc3a4, letra minúscula latina 1 com diérese) ou decomposto como U + 0061 U + 0308 (UTF-8 0x61cc88, letra minúscula latina a + diaeresis combinada )

O sistema de arquivos HFS + do OS X exige que todos os nomes de arquivos sejam armazenados na representação UTF-8 de sua forma totalmente decomposta . Em um nome de arquivo HFS +, "ä" DEVE ser codificado como 0x61cc88 e "ö" DEVE ser codificado como 0x6fcc88.

Tenho certeza de que o que está acontecendo aqui é que, quando você digita "Näyttökuva.png" na linha de comando, está "digitando" os caracteres na forma pré-composta. Quando o arquivo é criado, o sistema de arquivos decompõe os caracteres para armazenamento. Está tudo bem até agora. Mas quando você tenta usar o preenchimento de tabulação começando com "Nä", acho que o bash está falhando em decompor o "ä" antes de procurar por correspondências e, é claro, não encontra nenhuma.

Para ilustrar a diferença, aqui está um exemplo de qual codificação é usada quando eu apenas digito "Näyttökuva.png" na linha de comando, vs.

$ printf Näyttökuva.png | xxd    # This time I pasted the it in from this web page
0000000: 4ec3 a479 7474 c3b6 6b75 7661 2e70 6e67  N..ytt..kuva.png
$ touch Näyttökuva.png           # Also pasted from the web
$ printf Näyttökuva.png | xxd    # This time I tab-completed it after N
0000000: 4e61 cc88 7974 746f cc88 6b75 7661 2e70  Na..ytto..kuva.p
0000010: 6e67                                     ng

Agora, quanto à questão de os personagens se perderem ao excluir e refazer a tabulação, suspeito que isso esteja intimamente relacionado. Especificamente, acho que o bash está "excluindo" um ponto de código por pressionamento da tecla delete, mas apagando um caractere da janela Terminal por pressionamento. Como um dos caracteres excluídos ("ö" desta vez) consistia em dois pontos de código, mas apenas um caractere, a tela do Terminal fica fora de sincronia. Tente completar com tabulação o nome do arquivo inteiro, excluindo-o de volta para "Näytt" e, em seguida, preenchendo novamente a tabulação: o bash parece pensar que apenas a diérese combinada foi excluída, e não o "ö" inteiro, por isso, adiciona novamente a diátese combinada , mas desta vez anexa ao "t":

$ echo Näytkuva.png 
Näyttökuva.png

Observe que, quando pressiono return, o bash realmente tem o nome do arquivo inteiro; é apenas a tela do Terminal que estava confusa.

O TL; DR bash possui alguns bugs que lidam com caracteres acentuados decomponíveis.

EDIT: após algumas ponderações, acho que a única solução completa é corrigir o bash (/ aguarde seus desenvolvedores corrigi-lo). Também pode haver uma maneira de inserir caracteres em forma decomposta, mas não tenho idéia do que seria. Mas encontrei algumas soluções parciais:

  1. Arraste e solte um arquivo das pastas do Finder em sua forma correta. Como o Finder obtém o nome do arquivo do sistema de arquivos, ele já está decomposto, então funciona.

  2. Você pode realmente tab-complete o próprio personagem acentuado. Por exemplo, se você digitar "Na" e depois tab, corresponderá a "Näyttökuva.png" porque a decomposição canônica de "ä" começa com "a". Mas se você tiver um arquivo chamado "Narwal.gif" no mesmo diretório, isso não será muito útil ...

  3. Eu não testei isso, mas se você vincular a guia ao menu completo em vez de completo, deverá permitir a seleção de possíveis correspondências para que você possa selecionar o que deseja, mesmo que não possa digitar a próxima letra. (Ou você pode vinculá-lo a um pressionamento de tecla diferente, para poder usá-lo apenas quando precisar.)

  4. Para corrigir o problema com a exibição do Terminal fora de sincronia, você pode vincular algo à redesenho da linha atual - isso não impedirá que o problema aconteça, mas permitirá que você ressincronize a exibição.

Gordon Davisson
fonte
Obrigado, gostei da pipoca. Eu acho que você acertou a causa do problema: usando $ echo -e "N\xC3\xA4*" | ls(o eco dá Nä*) resultados Näyttökuva.png. O problema existe também com os outros shells no Mac OS; e com, por exemplo, o zsh ls Né auto-completado em #ls Na<0308>ytto<0308>kuva.png
Jari Keinänen 19/03
Eu também tentei o preenchimento automático e ls Nä*no bash no Xubuntu e ele funcionou corretamente, por isso é um bug entre o teclado e o OS X e o Terminal. Também testei isso na partição Bootcamp, mas o problema persiste (isto é, não acontece apenas com arquivos HFS +).
Jari Keinänen 19/03/11
(Agora você viu sua edição referente às soluções alternativas) Pelo menos os dois primeiros trabalhos. O # 2 é interessante: o preenchimento automático Nafunciona, mas Naynão (embora seja compreensível porque realmente existe ¨entre o ae y. No Xubuntu ls Na*não funciona (embora Nä*funcione, portanto não é realmente um problema). substituindo äe öcom a?e o?ex ls Na?y*claro que isso aumenta a ambiguidade, mas pode vir a calhar em alguns casos..
Jari Keinänen
2
O motivo pelo qual ele funciona no Xubuntu pode ser o fato de o sistema de arquivos usar o mesmo formato da interface do terminal. Se você faz ls N* | xxdno Xubuntu, ele fornece caracteres compostos ou decompostos?
Gordon Davisson
Supondo que o Xubuntu armazene o nome do arquivo na forma composta, tente executar o comando touch $'Na\xcc\x88ytto\xcc\x88kuva.png'e veja o que acontece - meu palpite é que ele criará um novo arquivo com um nome muito semelhante.
Gordon Davisson
4

Esta é uma pergunta antiga e não há resposta definitiva. Apenas soluções alternativas.

No entanto, combinei algumas informações deste guia antigo e como sugerido e instruído aqui :

Instalei uma festança mais recente no meu Snow Leopard. Após a instalação, a conclusão do bash funciona corretamente! (Snow Leopard enviado com 3.2.48 (1) e MacPorts instalado 4.2.45_1). Lembre-se de fazer as alterações em /etc/shellsexecução chsh.

Além disso, por causa de algumas outras instruções, tenho .inputrc:

set meta-flag on
set input-meta on
set output-meta on
set convert-meta off

Não tenho certeza se eles são necessários ou não para uma operação adequada.

Pinguim selvagem
fonte
Você está certo: o bash 4.2 é concluído (onde äé pré-composto), Näyttökuva.pngmas o bash 3.2 não.
Lri