首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >奇异的Konsole字符编码行为

奇异的Konsole字符编码行为
EN

Unix & Linux用户
提问于 2018-06-09 04:46:19
回答 1查看 741关注 0票数 1

我在Lubuntu中将Konsole的字符编码设置为UTF-16 (不确定Konsole是使用UTF-16小终端还是UTF-16大端)。

然后在“运行”窗口中运行以下命令:

然后,我按下键盘上的"a“按钮(在Lubuntu中选择的键盘布局是英语的),我认为它将导致字节61 00 (如果Konsole使用UTF-16小endian)发送到行规则,而行规则将依次将这些字节回显到Konsole,而Konsole将显示字符"a”。但我得到了以下信息:

我又一次按下了"a“按钮,得到了以下信息:

同样,我还按了"a“按钮,得到了以下内容:

同样,我还按了"a“按钮,得到了以下内容:

为什么我要得到这些奇怪的字符而不是简单地得到"aaaa"?

编辑:

这些字符显示在Konsole中:

幡‘懾䁞幡’懾䁞

EN

回答 1

Unix & Linux用户

回答已采纳

发布于 2018-06-09 09:24:10

让我们进一步强调,xxd -p是不相关的,我们不是在讨论它的输出。由于内核端的行缓冲,它甚至没有看到输入,因此没有产生任何输出。无论它的价值是什么,它也可以是一个cat或一个sleep 100000或其他什么。我们正在讨论内核(行规则)是如何回显输入的。

如果您切换回UTF-8,然后按回车到xxd -p,它的输出就像fffe6100fffe6100一样。所以很少有endian被确认(或者可能是体系结构的本地字节顺序),但令人惊讶的是,在每个字符之前都有一个BOM。这让我怀疑Konsole开发人员并没有很好地考虑,他们只是盲目地以UTF-16 (没有BE或LE指定)作为目标字符集,为每个可用的输入块调用iconv,并将其放置在其中。

让我们来看看它在连接到strace的文件描述符上所做的事情:

代码语言:javascript
复制
write(..., "\377\376a\0", 4)             = 4
[...]
read(..., "\377\376a^@", 5)              = 5

NUL字节(0x00)返回为文字^@,即0x5e和0x40。

a (0x61)一起,这将为您提供U+5e61,这正是您看到的第一个字形。另外,您将以一个字节结束,也就是说,下一个所谓的低字节将被解释为高字节,反之亦然。

对于字节0x00,内核只是简单地破坏了它的回显方式。对于其他字节,它也执行其他操作。例如,字节0x03 (^C)通常触发一个中断发送到前台进程,0x15 (^U)删除到目前为止输入的数据,0x0a和/或0x0d (即换行符)将数据刷新到应用程序,等等。所有这些字节都可以(而且确实)合法地出现在UTF-16表示字符中,并且您在输入时肯定不希望出现这些情况。

为了在行弟子上使用UTF-16,内核需要对此提供明确的支持,并且需要被告知正在使用这种编码(类似于stty utf16的代码)。据我所知,这没有实现(幸运的是,这完全是对开发人员资源的浪费)。内核期望使用与ASCII兼容的编码,而UTF-16则不是.

即使UTF-16是在tty行的内核中实现的,整个生态系统也必然是非常脆弱的。终端可以同时从多个源接收数据,并且无法保证所有数据生产者和所有传输者(例如ssh)始终保持字节成对耦合。一旦它按字节结束(如上面所示),其余的就无法使用了。

我现在更确定的是,没有正确地考虑过这一点。在我看来,UTF-16应该从他们提供的编码列表中删除,或者至少应该显示一个警告。我已经提交了魔芋虫395171

票数 1
EN
页面原文内容由Unix & Linux提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://unix.stackexchange.com/questions/448745

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档