trabalhando com nomes de arquivos em uma codificação diferente sobre ssh

7

Estou ssh'ing para um sistema remoto onde uma codificação diferente para os nomes de arquivos (e para as localidades dos usuários) foi usada. E isso causa alguns problemas.

Problemas resolvidos pela correspondência das configurações de localidade

Antes de passar para os problemas com nomes de arquivos, quero dizer que alguns problemas de codificação com essa sessão ssh são resolvidos por definindo a localidade remota para que corresponda à localidade local , ou seja,

  • os problemas com a edição da linha de comando (pressionei o Backspace trice, mas como no meu host a codificação é UTF-8 e no remoto - KOI8-R, ou talvez CP1251, algumas codificações cirílicas de 8 bits, isso não afetou minha string cirílica corretamente):

[imz@localhost ~]$ locale
LANG=ru_RU.UTF-8
LC_CTYPE="ru_RU.UTF-8"
LC_NUMERIC="ru_RU.UTF-8"
LC_TIME="ru_RU.UTF-8"
LC_COLLATE="ru_RU.UTF-8"
LC_MONETARY="ru_RU.UTF-8"
LC_MESSAGES="ru_RU.UTF-8"
LC_PAPER="ru_RU.UTF-8"
LC_NAME="ru_RU.UTF-8"
LC_ADDRESS="ru_RU.UTF-8"
LC_TELEPHONE="ru_RU.UTF-8"
LC_MEASUREMENT="ru_RU.UTF-8"
LC_IDENTIFICATION="ru_RU.UTF-8"
LC_ALL=
[imz@localhost ~]$ echo привет
привет
[imz@localhost ~]$ echo при
при
[imz@localhost ~]$ ssh -vv [email protected]
Last login: Fri Nov 25 13:44:56 2011 from NN.NN.NN.NN
[ivan@dell ~]$ locale
LANG=ru_RU.KOI8-R
LC_CTYPE="ru_RU.KOI8-R"
LC_NUMERIC="ru_RU.KOI8-R"
LC_TIME="ru_RU.KOI8-R"
LC_COLLATE="ru_RU.KOI8-R"
LC_MONETARY="ru_RU.KOI8-R"
LC_MESSAGES=POSIX
LC_PAPER="ru_RU.KOI8-R"
LC_NAME="ru_RU.KOI8-R"
LC_ADDRESS="ru_RU.KOI8-R"
LC_TELEPHONE="ru_RU.KOI8-R"
LC_MEASUREMENT="ru_RU.KOI8-R"
LC_IDENTIFICATION="ru_RU.KOI8-R"
LC_ALL=
[ivan@dell ~]$ echo привет
привет
[ivan@dell ~]$ echo при   
привÐ
[ivan@dell ~]$ export LANG=ru_RU.UTF-8
[ivan@dell ~]$ echo привет
привет
[ivan@dell ~]$ echo при
при
[ivan@dell ~]$ 
  • o problema com a compreensão correta da insensibilidade a maiúsculas e minúsculas para as cadeias processadas; agora iria funcionar, depois de definir o local:

[ivan@dell ~]$ echo привет | fgrep -i ВЕТ
привет
[ivan@dell ~]$ 

mas isso não funcionaria antes.

Pequenos problemas com nomes de arquivos

Os utilitários que imprimem nomes de arquivos (que, como você lembra, são armazenados remotamente em uma codificação diferente) não os imprimem na íntegra, mas substituem pontos de interrogação por caracteres estrangeiros:

[ivan@dell ~]$ find ~mama/Desktop/ -iname '*.xls'
/home/mama/Desktop/????????? ????????.xls
/home/mama/Desktop/???????? ??? ???????????? (1).xls
/home/mama/Desktop/???????? ??? ???????????? (2).xls
/home/mama/Desktop/???????? ??? ???????????? (3).xls
/home/mama/Desktop/???????? ??? ????????????.xls
[ivan@dell ~]$ find ~mama/Desktop/ -iname '*.xls' -print
/home/mama/Desktop/????????? ????????.xls
/home/mama/Desktop/???????? ??? ???????????? (1).xls
/home/mama/Desktop/???????? ??? ???????????? (2).xls
/home/mama/Desktop/???????? ??? ???????????? (3).xls
/home/mama/Desktop/???????? ??? ????????????.xls
[ivan@dell ~]$ 

O mesmo problema é exibido por ls e assim por diante. Mas isso pode ser facilmente superado passando-os como strings para comandos de impressão (que não estão cientes do problema com codificações não correspondentes dos nomes de arquivos e do terminal - ou por qualquer razão, mas funciona):

[ivan@dell ~]$ find ~mama/Desktop/ -iname '*.xls' -print0 | xargs -0 -n 1 echo 
/home/mama/Desktop/Êðåäèòíûé ïîðòôåëü.xls
/home/mama/Desktop/ÀÄÐÅÑÀÒÛ äëÿ ïîçäðàâëåíèé (1).xls
/home/mama/Desktop/ÀÄÐÅÑÀÒÛ äëÿ ïîçäðàâëåíèé (2).xls
/home/mama/Desktop/ÀÄÐÅÑÀÒÛ äëÿ ïîçäðàâëåíèé (3).xls
/home/mama/Desktop/ÀÄÐÅÑÀÒÛ äëÿ ïîçäðàâëåíèé.xls
[ivan@dell ~]$ 

Além disso, o fato de eles serem ilegíveis não era muito chato, porque eu sempre poderia anexar um | recode -f cp1251..utf-8 no final do comando.

O problema chato

O problema essencial é que selecionar (com um mouse) os nomes de arquivos no terminal e colá-los não funciona:

[ivan@dell ~]$ diff '/home/mama/Desktop/ÀÄÐÅÑÀÒÛ äëÿ ïîçäðàâëåíèé (1).xls' '/home/mama/Desktop/ÀÄÐÅÑÀÒÛ äëÿ ïîçäðàâëåíèé (3).xls'
diff: /home/mama/Desktop/ÀÄÐÅÑÀÒÛ äëÿ ïîçäðàâëåíèé (1).xls: No such file or directory
diff: /home/mama/Desktop/ÀÄÐÅÑÀÒÛ äëÿ ïîçäðàâëåíèé (3).xls: No such file or directory
[ivan@dell ~]$ 

Eu notei uma representação de escape dos nomes dos arquivos na saída de stat , então eu pude selecionar e colá-lo (dentro de $'' em bash ):

[ivan@dell ~]$ diff '/home/mama/Desktop/04051023 437 767400235501 (1).xls' '/home/mama/Desktop/04051023 437 767400235501 (3).xls'
diff: /home/mama/Desktop/04051023 437 767400235501 (1).xls: No such file or directory
diff: /home/mama/Desktop/04051023 437 767400235501 (3).xls: No such file or directory
[ivan@dell ~]$ diff $'/home/mama/Desktop/04051023 437 767400235501 (1).xls' $'/home/mama/Desktop/04051023 437 767400235501 (3).xls'
Files /home/mama/Desktop/ÀÄÐÅÑÀÒÛ äëÿ ïîçäðàâëåíèé (1).xls and /home/mama/Desktop/ÀÄÐÅÑÀÒÛ äëÿ ïîçäðàâëåíèé (3).xls differ
[ivan@dell ~]$ 

Então, a questão é:

How to conveniently work with remote filenames (over ssh), which are in a different encoding?

Seria legal se eles fossem legíveis, selecionáveis e pastáveis (e também tipáveis por mim no teclado e depois completados pelo Tab em bash ; para serem tipificáveis por mim convenientemente, eles devem ser legível, claro).

Estou trabalhando em urxvt em X.org no Linux no host local, e é bash em Linux no final remoto.

    
por imz -- Ivan Zakharyaschev 25.11.2011 / 18:40

2 respostas

2

Provavelmente, pode-se considerar o uso de alguns emuladores de terminal complexos como screen (em qualquer extremidade) que traduzam os caracteres (ou use alguma extensão de tradução para ssh ...), ou pode-se configurar um convmvfs vista do sistema de arquivos remotamente (com nomes de arquivos gravados na codificação local), mas há uma solução simples:

apenas crie um "ambiente" no host local especialmente para trabalhar com esse host remoto, e trabalhe nesse ambiente (execute ssh, etc.), ou seja, na situação em que os nomes de arquivos remotos estão em CP1251, inicie um novo terminal em X que funcionaria com essa codificação :

$ LC_CTYPE=ru_RU.CP1251 xvt &

e trabalhe com isso. (Se você gosta do console Linux mais do que X, provavelmente você pode configurar um console Linux virtual de acordo, mas o conhecimento sobre a configuração do console Linux está evaporando da minha cabeça ...)

    
por 25.11.2011 / 19:09
3

Dentro de um emulador de terminal que suporta UTF-8, você pode usar o luit comando para executar um subshell (ou outro programa) em um local diferente. A configuração de localidade que indica conjuntos de caracteres é LC_CTYPE .

LC_CTYPE=ru_RU.KOI8-R luit ls   # run one command
LC_CTYPE=ru_RU.KOI8-R luit      # start a shell (type Ctrl+D or exit to return to the parent shell)

Se você tiver uma árvore inteira de arquivos em uma codificação diferente, recomendo (se possível) montá-la através de convmvfs .

mkdir ~/net/[email protected] ~/net/[email protected]
sshfs [email protected]: ~/net/[email protected]
convmvfs -o srcdir=~/net/[email protected],icharset=KOI8-R,ocharset=UTF-8 ~/net/[email protected]
ls ~/net/[email protected]
    
por 26.11.2011 / 01:23