Je veux tail -f
un fichier, mais son contenu est en sjis
encodage, j'ai donc besoin de le convertir en encodage natif (utf-8) de mon terminal.
Quand je fais
queue -f x | iconv -fsjis
il n'y aura pas de sortie. Comme
queue x | iconv -fsjis
fonctionne, au début, je pensais que c'était un problème de mise en mémoire tampon, mais en essayant unbuffer
et stdbuf
comme décrit sur Désactiver la mise en mémoire tampon dans le tuyau n'a pas aidé.
En fait, même après que plus de 10k de données aient été ajoutées à x, il n'y aurait pas de sortie, donc je suppose que ce n'est pas un problème de mise en mémoire tampon (la mémoire tampon est de 4k, si je ne me trompe pas), mais iconv ne commencera à sortir que lorsque il reçoit un EOF.
Alors, comment puis-je suivre mon fichier encodé sjis ?
Réponse acceptée :
(prenez ceci avec des pincettes) Pour autant que je m'en souvienne, le problème réside dans la façon dont libiconv
œuvres. Les encodages multi-octets ont besoin d'une machine d'état pour les décoder, et libiconv
préfère recevoir des caractères entiers, vous ne pouvez donc pas lui donner un demi-caractère dans un appel de fonction et l'autre moitié dans le suivant.
Je peux penser à deux autres solutions, l'une est une bonne méthode hors bande, l'autre est un hack intrabande.
Modifier l'encodage de l'émulateur de terminal (hors bande) :l'une consiste à changer l'encodage des caractères dans votre émulateur de terminal, donc son encodage natif est Shift JIS. Je viens de vérifier konsole
, et le prend en charge. Dans le menu, Affichage→Encodage des caractères→Japonais→sjis. Vous pouvez alors simplement tail -f
le fichier, et konsole
se chargera de décoder les caractères multi-octets et de les faire correspondre aux glyphes de police.
Transcoder l'encodage du terminal à la volée (dans la bande ; meilleur) :courtoisie de Gilles, qui m'a rappelé luit
après très longtemps. Utilisez luit
, qui aurait dû venir avec votre distribution XOrg (sur Debian, c'est le paquet x11-utils
). Utilisez-le comme ceci :
$ luit -encoding SJIS -- tail -f x
Cela obligera le terminal à transcoder SJIS vers/depuis l'encodage de votre terminal et exécutera tail -f x
. L'inconvénient de luit
est qu'il ne prend pas en charge la richesse des encodages pris en charge par libiconv
. L'avantage est qu'il est disponible presque partout.
Transcoder l'encodage du terminal à la volée (in-band ; hack) :ttyconv
est un hack que j'ai écrit il y a de nombreuses années (initialement en C, puis refait en Python) qui utilise libiconv
pour transcoder les E/S du terminal. Il génère un nouveau pseudoterminal et (a) transcode les caractères que vous saisissez de votre encodage local vers l'encodage distant, et (b) transcode les caractères que vous recevez de l'encodage distant vers votre encodage local. Je l'ai utilisé pour parler à des serveurs qui utilisaient des encodages non pris en charge par les terminaux Linux standard. Veuillez noter que tous les encodages à distance avec lesquels je l'ai testé étaient des encodages à un octet, donc je ne peux pas garantir que cela fonctionnerait pour Shift JIS. Je ne trouve pas souvent d'appel à l'utiliser ces jours-ci, la plupart des systèmes passant à Unicode.
Voici comment vous l'utiliseriez :
$ ttyconv -rsjis -- tail -f x
L'inconvénient de ttyconv
c'est que je l'ai écrit, personne ne l'utilise sauf moi, c'est probablement plein de bugs. J'excelle dans ce domaine. L'avantage est qu'il utilise libiconv
, donc si votre encodage est inhabituel, c'est votre meilleur pari. Au dernier décompte, ttyconv --list
prend en charge 100 encodages.