管道/STDOUT/STDIN 中的数据是如何编码的?

Dar*_*ula 2 pipe character-encoding stdin

我最近一直在研究各种文本编码,但找不到任何关于如何在管道中编码数据的好来源。

以下是我的一些一般假设:

  1. 管道处理二进制,并且与编码无关
  2. 管道每一侧的应用程序(包括 STDOUT/STDIN)应该对文本编码格式达成共识
  3. 终端/控制台也算作这些应用程序之一,应该使用相同的编码。
  4. Unix 应用程序默认为 UTF-8,但可以更改。

这些准确吗?有人可以扩展这些在具有不同默认值的系统中如何工作吗?

继续提问:

  • 什么程序像cat发送到终端?他们在 unicode 中“思考”吗?或者他们只是读取字节并发送字节,由终端来解释编码文本?

我曾尝试在终端中更改编码,但似乎没有帮助。

$ printf 'ö' | hexdump
0000000 c3 b6
0000002
Run Code Online (Sandbox Code Playgroud)
$ export LANG=en_US.UTF-16
$ printf 'ö' | hexdump
0000000 c3 b6
0000002
Run Code Online (Sandbox Code Playgroud)

And*_*ton 7

我将在下面解决您的每一点:

  1. 管道处理二进制,与编码无关

  2. 管道每一侧的应用程序(包括 STDOUT/STDIN)应该对文本编码格式达成共识,
    我什至不会说文本编码;它不需要是文本(尽管通常是)。从管道读取的应用程序需要知道应用程序写入管道的预期结果。

  3. 终端/控制台也算作这些应用程序之一,应该使用相同的编码
    。终端不参与管道。如果我们考虑将进程的标准输出写入终端的情况,那么终端将解释这些字节。这可能是“文本”,或者告诉终端执行诸如清除屏幕或重新定位光标之类的操作的控制代码。

    例如,请考虑:

    $ clear | hexdump -c
    0000000 033   [   H 033   [   2   J 033   [   3   J
    
    Run Code Online (Sandbox Code Playgroud)

    那是<esc>[H<esc>[2J<esc>[3J; 它们是 ANSI 控制序列。终端将其转换为清除屏幕。有关更多信息,请参阅https://en.wikipedia.org/wiki/ANSI_escape_code

  4. Unix 应用程序默认为 UTF-8,但可以更改。
    同样,这与管道没有任何直接关系。我认为默认值是“C”,我认为这只是基本的 ASCII 字符集。在LANG环境变量通常控制编码程序使用的字符。

  • 请注意,有像 `iconv` 这样的实用程序可以在不同的编码之间进行转换。例如,`... | iconv -f ISO-8859-15 -t UTF-8 | ...` 将从其左侧管道接收 ISO-8859-15,并将 UTF-8 输出到其右侧管道。 (4认同)
  • 还可能值得一提的是,虽然 UTF-8 已经无处不在,但对于类 Unix 操作系统的大部分历史,一般假设是 7 位 ASCII 或(后来)8 位扩展(通常是 ISO Latin-1 AKA ISO 8859-1 或 Windows Latin-1 AKA CP1252)。(我们这些不得不处理冲突字符编码痛苦的人欢迎 UTF-8 变得普遍的前景!) (2认同)