CONSOLE_CODES(4) Linux Programmer's Manual CONSOLE_CODES(4)

控制終端程式碼 - Linux 控制終端轉義和控制序列

Linux控制檯實現了VT102和ECMA-48/ISO 6429/ANSI X3.64終端控制的子集, 這個子集很龐大,當然還有Linux自己私有的控制序列,以改變顏色配置,字元 集映像,等等.在下面將要給出的表格中,第二列為指定的功能給出了ECMA-48 或者DEC助記符(如果是後者會在前面加有DEC字首).沒有給出助記符的序列 既不是ECMA-48也不是VT102字元.

在所有標準輸出程序執行完畢,並且一個字元流被送到控制檯 驅動程式準備顯示出來的時候,所發生的第一件事就是將程序 使用的程式碼轉換成顯示使用的程式碼.

如果控制檯工作於 UTF-8 模式,那麼輸入的位元組會首先編碼 成16位的 Unicode 程式碼.如果不是UTF-8模式,那麼每個位元組 會按照當前的字元對映表完成轉換(轉換成Unicode編碼的值). 參看下面將要討論的 CHARACTER SETS 一章.

在一般情況下,Unicode 程式碼被轉換成為儲存在影片儲存器中的 字型索引,這樣對應的具體字元(字元儲存在影片ROM中)就顯示 在螢幕上了. 注意使用 Unicode 編碼允許我們同時使用 512 種不同的字型(和 計算機硬體有關).

如果當前的 Unicode 程式碼是一個控制字元,或者系統目前正在處 理一個轉義序列,處理的方式有些特別.它不會被轉換成字型索 引,也不會直接顯示在螢幕上.它可能控制游標的移動,或者實現 其它控制功能.參看下面的 LINUX CONSOLE CONTROLS 一節 所進行的討論.

一般來說直接在程式中插入終端控制字元並不是很好.Linux 支 持終端相容的 terminfo(5) 資料庫. 除了直接插入控制和轉義序列,也可以使用象 ncurses(3), tput(1), 或者 reset(1). 這樣的顯示庫或者工具.

這一段描述了所有在Linux控制檯下使用的呼叫特殊功能的控制字元 和轉義序列(例如.任何不在當前游標處插入可見字元的序列).

當一個字元在透過字元對映錶轉換之前含有以下14個程式碼之一的時 候表明它是一個控制字元. 00(NUL),07(BEL),08(BS),09(HT),0a(LF),0b(VT), 0c(FF),0d(CR),0e(SO),0f(SI),18(CAN),1a(SUB), 1b(ESC),7f(DEL). 我們可以透過設定 `顯示控制字元' 模式(見下文)以允許07,09,0b, 18,1a,7f 像普通字元一樣顯示在螢幕上.另一方面,在UTF-8模式下 所有位於 00-1f之間的程式碼都被認為是控制字元,而不管是否處於 `顯示控制字元'模式.

一個控制字元會立刻生效,然後被丟棄(即使是在轉義序列中間), 之後轉義序列才繼續處理下一個字元. (在任何情況下,ESC都表示一個新的轉義序列的開始,可能導致 前一個序列的非正常終止,CAN和SUB 終止任何轉義序列.) 可識別的控制字元是BEL,BS,HT,LF,VT,FF,CR,SO,SI,CAN, SUB,ESC,DEL,CSI.他們的功能如下.:

BEL(0x07,^G)鈴聲;

BS(0x08,^H)後退一格(在行首不起作用);

HT(0x09,^I)跳至下一個製表位.如果後面已沒有製表位則跳至行尾;

LF(0x0A,^J),VT(0x0B,^K),FF(0x0C,^L)三者都表示換行;

CR(0x0D,^M)回車並換行;

SO(0x0E,^N)啟用 G1 字符集, 如果設定了 LF/NL(新行模式)還要加上回車換行;

SI(0x0F,^O)啟用 G0 字符集;

CAN(0x18,^X),SUB(0x1A,^Z)兩者都表示中斷轉義序列;

ESC(0x1B,^[)開始一個新的轉義序列;

DEL(0x7F)忽略;

CSI(0x9B)等同於 ESC [;

ESC c RIS 重繪螢幕.
ESC D IND 換行.
ESC E NEL 新的一行.
ESC H HTS 設定當前列為製表位.
ESC M RI 翻轉換行(Reverse linefeed).
ESC Z DECID DEC 私有定義.核心將其解釋為
VT102字元,返回字元ESC [ ? 6 c.
ESC 7 DECSC 儲存當前狀態(游標座標,
屬性,字符集).
ESC 8 DECRC 恢復上一次儲存的設定
ESC [ CSI 控制序列介紹
ESC % 開始一個字符集選擇序列
ESC % @    選擇預設字符集(ISO 646 / ISO 8859-1)
ESC % G    選擇 UTF-8
ESC % 8    選擇 UTF-8(已不用)
ESC # 8 DECALN DEC 螢幕校準測試 - 以E's填充螢幕.
ESC( 開始一個 G0 字符集定義序列
ESC( B    選擇預設字符集(ISO 8859-1 mapping)
ESC( 0    選擇 vt100 圖形對映
ESC( U    選擇空對映 - 直接訪問字元ROM
ESC( K    選擇使用者對映 - 由程式mapscrn(8)
   載入.
ESC ) 開始一個 G1 字符集定義
(後面跟 B,0,U,K,同上).
ESC > DECPNM 設定數字小鍵盤模式
ESC = DECPAM 設定程式鍵盤模式
ESC ] OSC (是perating system command的縮寫)
ESC ] P nrrggbb: 設定調色盤,後面緊跟7個
十六進位制數,再跟一個 P :-(.
這裡 n 是顏色(0-16),而 rrggbb 表示
紅/綠/藍 值(0-255).
ESC ] R: 重置調色盤

CSI(或者 ESC [)後面跟的引數序列大部分是NPAR(16), 就是由分號隔開的十進位制數.空引數或缺少的引數以0處理. 可以用一個問號代替引數序列.

在任何情況下,系統讀取 CSI [(或者 ESC [ [)後的單個字元, 而忽略整個序列.(用於忽略回顯功能鍵.)

CSI 序列的動作由其最後一個字元決定.

@ ICH 用#符號指示空格.
A CUU 游標上移到#標識的行.
B CUD 游標下移到#標識的行.
C CUF 游標右移到#標識的列.
D CUB 游標左移到#標識的列.
E CNL 將游標下移到#指示的行的第一列.
F CPL 將游標上移到#指示的行的第一列.
G CHA 游標移動到當前行的指定列.
H CUP 游標移動到指定行和列(以1行1列為參照).
J ED 刪除(預設從當前游標處到行尾的)內容.
ESC [ 1 J: 刪除從開始到游標處的內容.
ESC [ 2 J: 清空整個螢幕.
K EL 刪除行(預設從當前游標處到結尾).
ESC [ 1 K: 刪除從行首到當前游標處的內容.
ESC [ 2 K: 刪除整行.
L IL 在空行插入#.
M DL 刪除#標記的行.
P DCH 刪除當前行中#標記的字元.
X ECH 刪除當前行中#標記的單詞.
a HPR 游標移動到#標記的右邊.
c DA 以`I am a VT102'應答 ESC [ ? 6 c:
d VPA 游標移動到當前列指定行
e VPR 游標移動到#標記的下一行.
f HVP 游標移動到指定的行和列.
g TBC 沒有引數: 清除當前位置的製表站.
ESC [ 3 g: 刪除所有制表站.
h SM 設定模式(見下文).
l RM 重置模式(見下文).
m SGR 設定屬性(見下文).
n DSR 狀態報告(見下文).
q DECLL 設定鍵盤指示燈.
ESC [ 0 q: 熄滅所有指示燈
ESC [ 1 q: 點亮 Scroll Lock 燈
ESC [ 2 q: 點亮 Num Lock 燈
ESC [ 3 q: 點亮 Caps Lock 燈
r DECSTBM 設定滾動範圍; 引數為首行和末行.
s ? 儲存游標位置.
u ? 恢復游標位置.
` HPA 游標移動到當前行指定列.

ECMA-48 SGR 序列 ESC [ <parameters> m 設定顯示屬性. 同樣的序列可以設定一個或多個屬性.

par 作用
0 所有屬性重設為預設值
1 設定粗體
2 設定亮度減半(在支援顏色顯示時用不同顏色進行模擬)
4 設定下劃線(在支援顏色顯示時用不同顏色進行模擬)
(用於模擬的顏色由 ESC ] ...設定)
5 設定閃爍
7 設定反轉影片(reverse video)
10 重設選定映像,顯示控制標記,
反轉元素標記.
11 選擇空映像,設定顯示控制標記,
重設反轉標記.
12 選擇空映像,設定顯示控制標記,
重設反轉標記.(在完成映像錶轉
換之前反轉標記引起每一位元組的
高位反轉.)
21 設定正常亮度(和 ECMA-48 不相容)
22 設定正常亮度
24 關閉下劃線
25 不閃爍
27 反轉影片關閉
30 黑色背景
31 紅色前景
32 綠色前景
33 棕色前景
34 藍色前景
35 品紅前景
36 孔雀藍前景
37 白色前景
38 開啟下劃線,設定預設前景色
39 關閉下劃線,設定預設前景色
40 黑色背景
41 紅色背景
42 綠色背景
43 棕色背景
44 藍色背景
45 品紅背景
46 孔雀藍背景
47 白色背景
49 設定預設背景色

DECCRM(預設關閉): 顯示控制字元.
DECIM(預設關閉): 設定插入模式.
LF/NL(預設關閉): 自動在CR後加上 LF,VT 或者 FF.

裝置狀態報告(DSR): 以 ESC [ 0 n 應答(終端準備好).
游標位置報告(CPR): 以ESC [ y ; x R 應答, 這裡 x,y 指游標位置.

這裡給出的序列在 ECMA-48中沒有描述.我們列出了設定模式序列; 用l替換最後一個h就是重設模式序列.

DECCKM(預設關閉): 開啟時游標鍵送出 ESC O 字首, 而不是 ESC [.
DECCOLM(預設 = 80 行): 交替選擇 80/132 行模式.當原顯示 模式不足以滿足要求的時候,象 resizecons(8) 這樣的使用者程式會改變終端顯示卡的硬體註冊.
DECSCNM(預設關閉): 設定影片反轉模式.
DECOM(預設關閉): 開啟時,游標位置用相對於捲軸左上角 的位置表示.
DECAWM(預設關閉): 開啟自動換行.在這種模式下,一行中 超過80列的字元將自動換行(在DECCOLM開啟時是132列).
DECARM(預設關閉): 開啟鍵盤自動重複.
X10 滑鼠報告(預設關閉): 設定報告模式 1(或者重設為 0)- 見下文.
DECCM(預設開啟): 設定游標可見.
X11 滑鼠報告(預設關閉): 設定報告模式 2(或者重設為 0)- 見下文.

下面的序列既不屬於 ECMA-48 字元也不屬於 VT102.它們只在 Linux控制檯上使用.顏色採用 SGR 引數: 0 = 黑色,1 = 紅色,2 = 綠色,3 =褐色 ,4 = 藍色,5 = 洋紅,6 = 孔雀藍,7 = 白色.

ESC [ 1 ; n ] 設定下劃線顏色為 n
ESC [ 2 ; n ] 設定暗色為 n
ESC [ 8 ] 設定當前顏色對為預設屬性.
ESC [ 9 ; n ] 設定螢幕空白超時為 n 分鐘.
ESC [ 10 ; n ] 設定機箱喇叭鳴叫頻率,單位: Hz.
ESC [ 11 ; n ] 設定機箱喇叭鳴叫持續時間,單位:微秒.
ESC [ 12 ; n ] 設定指定控制檯前臺執行.
ESC [ 13 ] 設定指定控制檯黑色
ESC [ 14 ; n ] 設定 VESA 關閉間隔,單位: 分鐘.

核心可以完成以下四種字元轉換,使字元能在螢幕上顯示. a)Latin1 -> PC,b)VT100 graphics -> PC,c)PC -> PC, d)user-defined(使用者自定義).

有兩種字符集設定,以 G0 和 G1定義,當前字符集必定是其中之一.(初 始化為G0.)鍵入 ^N 使 G1 成為當前字符集,鍵入 ^O 使 G0 成為當前設定.

變數 G0 and G1 指向字元對映關係表,並且這種指向關係可以由使用者改變. 系統初始化時它們分別指向表 a)and b). 序列 ESC( B ,ESC( 0 ,ESC( U 和 ESC( K 分別使 G0 指向字元對映表
a),b),c)和 d). 序列 ESC )B ,ESC )0 ,ESC )U 和 ESC )K 分別使 G1 指向字元對映表 a),b),c)和 d).

序列 ESC c 重置一個終端,當螢幕顯示出現混亂時可以使用這個序列. 另一個序列 "echo ^V^O" 僅僅將G0設為當前字符集,但並不保證 G0 指 向對映表 a). 有的Linux發行版中提供一個叫做 reset(1) 的程式用來送出序列 "echo ^[c". 如果你的系統終端變數沒有錯誤( rs1=\Ec), 那麼使用"tput reset"也可以達到同樣效果.

使用者自定義對映表可以用程式 mapscrn(8). 定義.這個程式工作時會將送入的字元c透過關係式s=map[c]對映到 字元s然後送入視訊記憶體.字元s所對應的點陣圖放在字元ROM裡面,可以使 用程式 setfont(8).

來改變.

滑鼠軌跡工具可以返回與 xterm 相容的滑鼠狀態報告.因為控制檯 驅動沒有辦法知道滑鼠型別,只有當虛擬終端驅動接收到滑鼠輸入 輸出訊息更新時才會將這些報告返回給控制檯輸入流..這些滑鼠 輸入輸出訊息由 gpm(8) 守護程序產生.

所有滑鼠軌跡轉義序列引數由xterm 編碼成象value+040 這樣的單一字元形式的數字引數.比如,`!' 編碼成 1.螢幕座標系統 以'1'為基準.

X10 相容模式在滑鼠鍵按下時將按下的鍵和滑鼠位置編碼後送出. ESC [ ? 9 h 允許這一動作,ESC [ ? 9 l禁止這一動作. 有鍵按下時,xterm 送出ESC [ M bxy(6 個字元).這裡 b 代表 鍵-1,而 xy 是滑鼠的 x 和 y 座標.這和 核心產生的序列相同.

常規的軌跡模式(Linux 2.0.24不再支援)在左右兩鍵同時按下然後 釋放時送出轉義序列.組合鍵編碼也被送出.ESC [ ? 1000 h 允許這 個動作而ESC [ 1000 l 禁止這個動作.當有鍵按下或者釋放時, xterm 送出 ESC [ M bxy.b 的低兩位對按鍵資訊編碼: 0=滑鼠鍵1按下,1=滑鼠鍵2 按下,2=滑鼠鍵3 按下,3=釋放. 高位編碼代表組合鍵,和上述編碼一起送出: 4=Shift,8=Meta(Alt),16=Control(Ctrl).xy為發生滑鼠事 件的x和y座標.以左上角為(1,1).

和其它終端的比較

我們已經討論了幾種終端型別,比如Linux 控制檯.這類終端稱為 "VT100相容"的終端.這裡我們再介紹其他兩種重要的終端型別: DEC VT102 和 xterm(1) 以及他們和Linux控制終端的區別.

vt102 也使用以下控制序列:

NUL(0x00)忽略;

ENQ(0x05)觸發應答訊息;

DC1(0x11,^Q,XON)繼續傳送;

DC3(0x13,^S,XOFF)使 vt100 忽略(並停止傳送) 除 XOFF and XON 以外的一切字元.

VT100-like DC1/DC3 程序可以由 tty 驅動啟用.

程式 xterm (在 vt100 模式 中)使用控制序列 BEL,BS,HT,LF,VT,FF,CR,SO,SI,ESC.

VT100 控制檯序列不完全支援Linux控制檯序列:

ESC N SS2 僅僅為下一個字元選擇 G2 字符集
(Single shift 2).
ESC O SS3 僅僅為下一個字元選擇 G2 字符集
(Single shift 2).
ESC P DCS 裝置控制字元,由ESC \ 終止
(Device control string).
ESC X SOS 字串開始.
(Start of string)
ESC ^ PM 私有訊息,由 ESC \ 終結
(Privacy message)
ESC \ ST 字串終結
(String terminator)
ESC * ... 指定 G2 字符集
ESC + ... 指定 G3 字符集

程式 xterm (vt100 模式)承認 ESC c,ESC # 8,ESC >,ESC =, ESC D,ESC E,ESC H,ESC M,ESC N,ESC O,ESC P ...ESC ESC Z(以 [ ? 1 ; 2 c,`I am a vt100 with advanced video option'迴應) 以及 ESC ^ ...ESC 意義同上. 接受 ESC(,ESC ),ESC *,ESC + 後跟 0,A,B 的字元序列,分別 代表的DEC 特殊字元,畫線設定,UK 和 US ASCII碼. 接受 ESC ] 作為特定資源設定:

ESC ] 0 ; txt BEL 將圖示名和視窗標題設為文字.
ESC ] 1 ; txt BEL 將圖示名設為文字.
ESC ] 2 ; txt BEL 將視窗名設為文字.
ESC ] 4 6 ; name BEL 改變日誌檔名(一般
由編譯時選項禁止)
ESC ] 5 0 ; fn BEL 字型設定為 fn.

以下字元的含義略有不同::

ESC 7 DECSC 儲存游標位置
ESC 8 DECRC 恢復游標位置

它還接受以下序列:

ESC F 游標移動到螢幕左下角(由
hpLowerleftBugCompat 開啟這項設定)
ESC l 記憶體鎖定(對於 HP 終端).
鎖定游標以上的記憶體.
ESC m 記憶體解鎖(對於 HP 終端).
ESC n LS2 呼叫 G2 字符集.
ESC o LS3 呼叫 G3 字符集.
ESC | LS3R 以GR呼叫 G3 字符集.
在xterm上看不到效果.
ESC } LS2R 以GR呼叫 G3 字符集.
在xterm上看不到效果.
ESC ~ LS1R 以GR呼叫 G3 字符集.
在xterm上看不到效果.

它不識別 ESC % ...

程式 xterm (直到 XFree86 3.1.2G)不能識別閃爍或者不可見模式的 SGR值.X11R6 也不能識別以 SGRs 為引數設定的色彩. xterm 可以識別其他的 ECMA-48 CSI 序列,只要Linux可以識別. 反之亦然.

xterm 可以識別以上列出的所有 DEC 私有序列,但是不包括 Linux 私有模式序列. 在 Xterm Control Sequences 中有關於 xterm 的私有模式序列的討論.

document by Edward Moy and Stephen Gildea,available with the X distribution.

在版本為 2.0.23 的核心中,CSI 序列的識別有些問題: 不能識別轉義序列中的NUL.

參見

console(4), console_ioctl(4), charsets(7)

本頁面中文版由中文 man 手冊頁計劃提供。
中文 man 手冊頁計劃:https://github.com/man-pages-zh/manpages-zh

October 31, 1996 Linux