Bash

人物去哪兒了?

  • July 10, 2022

\u有效的 shell(bash +4.3、ksh93 或 zsh)中,我們可以列印 Unicode 字元:

$ printf 'a b c \ua0 \ua1 \ua2 \ua3 \n'
a b c   ¡ ¢ £

這是來自Latin-1_Supplement範圍的一些字元。

但是,一旦9f添加了 Unicode 字元,列印就會停止,直到 Unicode9c被列印出來。

\u9f\u9c(APC 和 ST) 都是控製C1字元

$ printf 'a b c \u9f d e f \u9c \ua0 \ua1 \ua2 \ua3 \n'
a b c    ¡ ¢ £ 

字元 def 消失。

可以肯定的是,它printf正在生成所有字元,並且將輸出重定向到其他一些軟體(不是終端)將顯示生成的字元:

$ printf 'a b c \u9f d e f \u9c \ua0 \ua1 \ua2 \ua3 \n' | od -A n -tx1
61 20 62 20 63 20 c2 9f 20 64 20 65 20 66 20 c2
9c 20 c2 a0 20 c2 a1 20 c2 a2 20 c2 a3 20 0a

這足以證明正在生成字元。那麼,為什麼它們沒有被列印(顯示有一些可見的字形)?

我的問題是:

  1. 實際上是APC連接到ST。它在哪裡定義?
  2. 這兩個字元之間的字元是否發送到某個應用程序?
  3. 如果是這樣,適用於哪個應用程序?
  4. 誰負責這種重定向?外殼,終端或其他東西?

編輯

和終端都xterm不會konsole刪除d e f字元。

這證實這是終端應用程序的內部問題,而不是外殼。還沒有找到定義的地方。

APC 是否實際連接到 ST。它在哪裡定義?

這些控製字元實際上並不是 Unicode 的原始字元,而是繼承自舊的字元集規範,例如ECMA-48、ISO/IEC 6429 和 ISO/IEC-8859 系列字元編碼。從廣義上講,這些標准在 C1 控製字元上基本上是相互一致的(因為它們相互向後兼容,甚至還兼容一些更舊的規範)。

由於 ISO/IEC 6429 的副本正在出售,我不希望在網際網路上找到免費的合法副本,但 ECMA-48 說:

8.3.2 APC - 應用程序命令

符號:(C1)

表示:09/15 或 ESC 05/15

APC 用作應用程序使用的控製字元串的開始分隔符。後面的命令字元串可能由 00/08 到 00/13 和 02/00 到 07/14 範圍內的位組合組成。控製字元串由終止分隔符 STRING TERMINATOR (ST) 關閉。命令字元串的解釋取決於相關的應用程序。

和:

8.3.143 ST - 字元串終止符

符號:(C1)

表示:09/12 或 ESC 05/12

ST 用作由應用程序命令 (APC)、設備控製字元串 (DCS)、作業系統命令 (OSC)、隱私消息 (PM) 或字元串開始 (SOS) 打開的控製字元串的結束分隔符。

Unicode 在 C1 控製字元範圍內只定義了一個控製字元:U+0085 Next Line (NEL)。對於 C1 範圍內的任何其他字元,規範的這一部分適用:

控制程式碼的語義通常由使用它們的應用程序確定。但是,在沒有特定應用用途的情況下,可以根據 ISO/IEC 6429:1992 中規定的控制功能語義來解釋它們。

我無法在這裡驗證它,但我希望 ISO/IEC 6429 與 ECMA-48 所說的非常接近,如上所述。此外,終端的作者可能認為“向後兼容 pre-Unicode 7 位和 8 位字元編碼,如 ECMA-48”是一種特定的應用程序用途

因此,終端可能會合法地將 APC 和 ST 之間的字元解釋為“我不知道這些是做什麼用的,但我肯定知道這些不打算顯示為正常輸出。”

終端可能會或可能不會以某種方式對封裝在 APC 和 ST 之間的特定字元串做出反應,並忽略任何不匹配的字元串。由於終端視窗是“人類之前的最後一步”,因此當然可以假設到達它的任何應用程序命令字元串都是為了讓終端解釋和操作(如果適用),以及任何無法辨識的此類字元串由終端必須是錯誤的。

顯示“無效編碼”字元或其他錯誤消息是不合適的,因為該字元串被有效地編碼為“特定於應用程序的控製字元串,而不是用於顯示”。因此,對於題為“角色要去哪裡?”的問題的答案。最有可能:它們作為無效控製字元串的一部分被丟棄

但請注意,Unicode 規範說“……可能被解釋……”,而不是“……必須被解釋……”。因此,其他終端實現選擇只是將APC和ST字元作為沒有適用意義的不可列印控製字元忽略也不一定是無效的。

Stack Overflow 上的這個問題還討論了涉及 APC 和 ST 控製字元的控制序列。

那裡接受的答案說:

現實情況是,APC 很少被實施——大多數係統從不生成 APC 序列並默默地忽略任何接收到的序列。任何應用程序都不應發送或解釋 APC 序列,除非它知道連接的另一端正在以特定方式使用它們——例如通過配置選項來啟用它們,或者它(以某種方式)知道正在使用哪個終端仿真器,並且知道終端仿真器賦予它們特定的含義

$$ … $$

引用自:https://unix.stackexchange.com/questions/709189