(用少许盐腌制)据我所知,问题出在libiconv
工作方式上。多字节编码需要状态机对其进行解码,并且libiconv
喜欢接收整个字符,因此您不能只在一个函数调用中给它一半字符,而在下一个函数调用中给另一个字符。
我可以想到另外两种解决方案,一种是好的带外方法,另一种是带内黑客。
更改终端仿真器编码(带外):一种方法是更改终端仿真器中的字符编码,因此其本机编码为Shift JIS。我刚刚检查了konsole
,并对此表示支持。从菜单中,查看→字符编码→日语→sjis。然后tail -f
,您可以只是文件,并且konsole
将负责解码多字节字符并将其与字体字形匹配。
动态转码终端编码(带内;最佳):由Gilles提供,他让我想luit
了很长时间。使用luit
,它应该随XOrg发行版一起提供(在Debian中,它是package x11-utils
)。像这样使用它:
$ luit -encoding SJIS -- tail -f x
这将使终端将SJIS与您的终端编码进行代码转换,然后运行tail -f x
。缺点luit
是它不支持所支持的大量编码libiconv
。好处是几乎所有地方都可以使用它。
动态地对终端进行代码转换(带内;破解):这ttyconv
是我多年前写的一种hack(最初是用C语言编写的,后来又用Python重做),用于libiconv
对终端I / O进行代码转换。它产生一个新的伪终端,并且(a)将您键入的字符从本地编码转换为远程编码,并且(b)将您从远程编码接收的字符转换为本地编码。我用它来与使用标准Linux终端不支持的编码的服务器通信。请注意,我测试过的所有远程编码都是单字节编码,所以我不能保证它可以用于Shift JIS。这些天来,随着大多数系统切换到Unicode,我并不经常使用它。
这是您将如何使用它:
$ ttyconv -rsjis -- tail -f x
缺点ttyconv
是我写了它,没有人使用它,但是我可能是个bug。我擅长这一点。好处是,它使用libiconv
,因此,如果您的编码不正常,那是您最好的选择。最后,ttyconv --list
支持100种编码。