"tail -f | iconv -fsjis" 不输出任何内容

Evg*_*sky 15 tail buffer

我想要tail -f一个文件,但它的内容是sjis编码的,所以我需要将它转换为我的终端的本机 (utf-8) 编码。

当我做

尾-fx | iconv -fsjis

不会有输出。作为

尾巴 x | iconv -fsjis

确实有效,起初我认为这是一个缓冲问题,但尝试unbufferstdbuf按照关闭管道中的缓冲没有帮助。

实际上,即使在 x 中添加了 10k 以上的数据,也不会有输出,所以我想这不是缓冲问题(缓冲区是 4k,如果我没记错的话),但是 iconv 只会在它收到一个EOF。

那么我怎样才能跟随我的 sjis 编码文件呢?

Ale*_*ios 12

(加一点盐)据我所知,问题在于工作方式libiconv。多字节编码需要一个状态机来解码它们,并且libiconv更喜欢接收整个字符,所以你不能在一个函数调用中只给它半个字符,而在下一个函数调用中给它另一半。

我可以想到另外两种解决方案,一种是很好的带外方法,另一种是带内黑客。

更改终端仿真器编码(带外):一种是更改终端仿真器中的字符编码,因此其本机编码为 Shift JIS。我刚刚检查过konsole,并且支持这一点。从菜单中,查看?字符编码?日本语?sjis。然后tail -f,您可以只使用该文件,并konsole负责解码多字节字符并将它们与字体字形匹配。

即时转码终端编码(带内;最佳):由 Gilles 提供,他luit在很长一段时间后提醒我。使用luit,它应该与您的 XOrg 发行版一起提供(在 Debian 上,它是 package x11-utils)。像这样使用它:

$ luit -encoding SJIS -- tail -f x
Run Code Online (Sandbox Code Playgroud)

这将使终端将 SJIS 转码为/从您的终端编码,并运行tail -f x. 缺点luit是它不支持libiconv. 好处是它几乎无处不在。

即时转码终端编码(带内;hack)ttyconv是我多年前写的一个 hack(最初用 C,后来用 Python 重做),用于libiconv对终端 I/O 进行转码。它生成一个新的伪终端,并且 (a) 将您键入的字符从本地编码转码为远程编码,以及 (b) 将您从远程编码接收到的字符转码为本地编码。我用它来与使用标准 Linux 终端不支持的编码的服务器通信。请注意,我测试的所有远程编码都是单字节编码,所以我不能保证它适用于 Shift JIS。这些天我不经常使用它,因为大多数系统都切换到 Unicode。

这是你将如何使用它:

$ ttyconv -rsjis -- tail -f x
Run Code Online (Sandbox Code Playgroud)

缺点ttyconv是我写了它,除了我没有人使用它,它可能充满了错误。我擅长这一点。好处是它使用libiconv,所以如果你的编码不​​寻常,这是你最好的选择。最后统计,ttyconv --list支持 100 种编码。

  • 现在,有 [`luit`](http://www.pps.jussieu.fr/~jch/software/luit/),这是标准 X11 实用程序套件的一部分,类似于您的 `ttyconv`。 (2认同)