Quero tail -f
um arquivo, mas seu conteúdo está em sjis
codificação, então preciso convertê-lo para a codificação nativa (utf-8) do meu terminal.
Quando eu faço
cauda -fx | iconv -fsjis
não haverá saída. Como
cauda x | iconv -fsjis
funciona, a princípio pensei que fosse um problema de buffer, mas tentando unbuffer
e stdbuf
conforme descrito emDesative o buffer no pipenão ajudou.
Na verdade, mesmo depois de mais de 10k de dados serem adicionados a x, não haveria saída, então acho que não é um problema de buffer (o buffer é de 4k, se não me engano), mas o iconv só começará a produzir quando ele recebe um EOF.
Então, como posso seguir meu arquivo codificado em sjis?
Responder1
(leve isso com uma pitada de sal) Pelo que me lembro, o problema está na forma como libiconv
funciona. As codificações multibyte precisam de uma máquina de estado para decodificá-las e libiconv
preferem receber caracteres inteiros; portanto, você não pode fornecer apenas metade de um caractere em uma chamada de função e a outra metade na próxima.
Posso pensar em outras duas soluções, uma é um bom método fora de banda, a outra é um hack dentro da banda.
Alterar a codificação do emulador de terminal (fora da banda): uma é alterar a codificação de caracteres em seu emulador de terminal, para que sua codificação nativa seja Shift JIS. Acabei de verificar konsole
e é compatível com isso. No menu, Exibir→Codificação de caracteres→Japonês→sjis. Você pode então apenas tail -f
o arquivo e konsole
cuidará da decodificação dos caracteres multibyte e da correspondência deles com os glifos da fonte.
Transcodifique a codificação do terminal em tempo real (dentro da banda; melhor): cortesia de Gilles, que me lembrou luit
depois de muito tempo. Use luit
, que deveria vir com sua distribuição XOrg (no Debian, é package x11-utils
). Use assim:
$ luit -encoding SJIS -- tail -f x
Isso fará com que o terminal transcodifique SJIS de/para a codificação do seu terminal e execute tail -f x
. A desvantagem luit
é que ele não suporta a riqueza de codificações suportadas pelo libiconv
. A vantagem é que está disponível em quase todos os lugares.
Transcodifique a codificação do terminal em tempo real (in-band; hack):ttyconv
é um hack que escrevi há muitos anos(inicialmente em C, posteriormente refeito em Python) que usa libiconv
para transcodificar a E/S do terminal. Ele gera um novo pseudoterminal e (a) transcodifica os caracteres que você digita da codificação local para a codificação remota e (b) transcodifica os caracteres que você recebe da codificação remota para a codificação local. Usei-o para conversar com servidores que usavam codificações não suportadas pelos terminais Linux padrão. Observe que todas as codificações remotas com as quais testei eram codificações de byte único, portanto não posso garantir que funcionaria para Shift JIS. Não costumo encontrar chamadas para usá-lo atualmente, com a maioria dos sistemas mudando para Unicode.
É assim que você o usaria:
$ ttyconv -rsjis -- tail -f x
A desvantagem ttyconv
é que eu escrevi, ninguém usa além de mim, provavelmente está cheio de bugs. Eu sou excelente nisso. A vantagem é que ele usa libiconv
, portanto, se sua codificação for incomum, é sua melhor aposta. Na última contagem, ttyconv --list
suporta 100 codificações.
Responder2
Semelhante a ttyconv
também existe tconv
, escrito em C por Rich Felker.