我最近一直在研究各种文本编码,但无法找到有关如何在管道中对数据进行编码的任何好的来源。
以下是我的一些一般假设:
- 管道处理二进制,并且与编码无关
- 管道两端的应用程序(包括 STDOUT/STDIN)应该对文本编码格式达成共识
- 终端/控制台也算作这些应用程序之一,并且应该使用相同的编码。
- Unix 应用程序默认使用 UTF-8,但可以更改。
这些准确吗?有人可以扩展这些在具有不同默认值的系统中如何工作吗?
继续提问:
- 程序会
cat
向终端发送什么内容?他们用unicode“思考”吗?或者它们只是读取字节并发送字节,然后由终端来解释编码文本?
我尝试过更改终端中的编码,但似乎没有帮助。
$ printf 'ö' | hexdump
0000000 c3 b6
0000002
$ export LANG=en_US.UTF-16
$ printf 'ö' | hexdump
0000000 c3 b6
0000002
答案1
我将在下面解决您的每一点:
管道处理二进制,并且与编码无关
正确的。管道两端的应用程序(包括 STDOUT/STDIN)应该对文本编码格式达成共识
我什至不会说文本编码;它不一定是文本(尽管通常是文本)。从管道读取的应用程序需要知道写入管道的应用程序会发生什么。终端/控制台也算作这些应用程序之一,并且应该使用相同的编码
终端不参与管道。如果我们考虑将进程的标准输出写入终端的情况,那么终端将解释这些字节。这可能是“文本”,或者是告诉终端执行诸如清除屏幕或重新定位光标之类的操作的控制代码。
作为一个例子,请考虑:$ clear | hexdump -c 0000000 033 [ H 033 [ 2 J 033 [ 3 J
那是
<esc>[H<esc>[2J<esc>[3J
;它们是 ANSI 控制序列。终端将其翻译为清除屏幕。看https://en.wikipedia.org/wiki/ANSI_escape_code了解更多相关信息。Unix 应用程序默认使用 UTF-8 但可以更改
同样,这与管道没有任何直接关系。我认为默认值是“C”,我相信这只是基本的 ASCII 字符集。环境LANG
变量通常控制程序使用的字符编码。