關(guān)于ANSI轉(zhuǎn)義序列解讀
ANSI轉(zhuǎn)義序列
概念
先看ANSI_escape_code官網(wǎng)上的一段介紹:
In computing, ANSI escape codes (or escape sequences) are a method using in-band signaling
to control theformatting, color, and other output options on video text terminals.To encode
this formatting information, certain sequences of bytes are embedded into the text,which the
terminal looks for and interprets as commands, not ascharacter codes.
- 在計(jì)算機(jī)系統(tǒng)中,ANSI轉(zhuǎn)義碼(或轉(zhuǎn)義序列)是一種使用帶內(nèi)信號(hào)控制視頻文本終端的格式、顏色和其他輸出選項(xiàng)的方法。
- 為了編碼這種格式化信息,特定的字節(jié)序列被嵌入到文本中,終端將查找并將其解釋為命令,而不是字符代碼。
終端,現(xiàn)在也叫命令行,在歷史上,確實(shí)有一種設(shè)備就叫終端。其中最為著名的,可能就是 vt100 系列了。我們現(xiàn)在能看到的 terminal 軟件都是終端設(shè)備的模擬器。雖說(shuō)終端設(shè)備已經(jīng)作古,但終端的通信控制協(xié)議依然有效。
ANSI轉(zhuǎn)義序列
就是終端上通用的通信控制協(xié)議,我們可以在命令行下顯示粗體、斜體、下劃線字符,也可以顯示不同的顏色,甚至還能顯示簡(jiǎn)單的動(dòng)畫(huà)。
ANSI序列是在二十世紀(jì)七十年代引入的標(biāo)準(zhǔn),用以取代特定終端供應(yīng)商的序列,并在二十世紀(jì)八十年代早期開(kāi)始在計(jì)算機(jī)設(shè)備市場(chǎng)上廣泛使用。
與早期缺少光標(biāo)移動(dòng)功能的系統(tǒng)相比,新生的電子公告板系統(tǒng)(BBS)使用ANSI序列改進(jìn)其顯示。正是因?yàn)檫@個(gè)原因,ANSI序列變成了所有制造商共同采用的標(biāo)準(zhǔn)。
在21世紀(jì),盡管硬件文本終端已經(jīng)越來(lái)越少了,但ANSI標(biāo)準(zhǔn)依然存在,因?yàn)榇蠖鄶?shù)終端模擬器會(huì)對(duì)部分ANSI轉(zhuǎn)義序列進(jìn)行解釋。一個(gè)值得注意的例外是,在微軟Windows 10更新TH2之前,Windows操作系統(tǒng)的Win32控制臺(tái)是不支持ANSI轉(zhuǎn)義序列的。
歷史
最初,幾乎每個(gè)視頻終端制造商都各自添加了特定的轉(zhuǎn)義序列用于執(zhí)行一些特殊操作,比如把光標(biāo)置于屏幕上的某個(gè)位置。舉例來(lái)說(shuō),VT52終端允許通過(guò)發(fā)送ESC字符、y字符,后面跟上兩個(gè)等于x,y位置的數(shù)值加上32的字符(這是為了從ASCII空格字符開(kāi)始,并避開(kāi)控制字符),將光標(biāo)置于屏幕上的x,y位置。
由于這些序列對(duì)于不同的終端并不一樣,因此人們不得不開(kāi)發(fā)了一些復(fù)雜的庫(kù),比如termcap和實(shí)用程序,比如tput,以便程序可以使用同一套API應(yīng)對(duì)各種終端。另外,在很多終端中需要借助字符的二進(jìn)制值發(fā)送數(shù)字確定光標(biāo)的行和列)。對(duì)于某些編程語(yǔ)言,以及內(nèi)部不使用ASCII的系統(tǒng)來(lái)說(shuō),把數(shù)字轉(zhuǎn)換為正確的字符常常是有困難的,甚至完全做不到。
ANSI標(biāo)準(zhǔn)試圖解決這些問(wèn)題。標(biāo)準(zhǔn)制訂了一種所有終端共享的指令集,并要求用ASCII的數(shù)字字符傳遞所有數(shù)值信息。該系列的第一個(gè)標(biāo)準(zhǔn)是1976年通過(guò)的ECMA-48。它是一系列字符編碼標(biāo)準(zhǔn)的延續(xù),其中第一個(gè)是從1965年的ECMA-6,一個(gè)7位標(biāo)準(zhǔn),ISO 646就源自此標(biāo)準(zhǔn)。“ANSI轉(zhuǎn)義序列”的名稱可以追溯到1979年ANSI采用ANSI X3.64。此外,ANSI X3L2委員會(huì)與ECMA委員會(huì)TC 1合作制訂了一個(gè)幾乎一模一樣的標(biāo)準(zhǔn)。以上兩個(gè)標(biāo)準(zhǔn)合并為ISO 6429的國(guó)際標(biāo)準(zhǔn)。1994年,ANSI取消了其標(biāo)準(zhǔn),以支持國(guó)際標(biāo)準(zhǔn)。
第一個(gè)支持這個(gè)標(biāo)準(zhǔn)的流行視頻終端是1978年推出的Digital VT100。這個(gè)終端在市場(chǎng)上非常成功,引發(fā)了各種各樣的仿制品,其中最早和最流行的是1979年的Zenith Z-19。其他品牌還有Qume QVT-108,Televideo TVI-970,Wyse WY-99GT。另外,許多其他品牌的終端也不同程度地兼容可選的“VT100”、“VT103” 或 “ANSI”模式。 隨著越來(lái)越多的軟件(尤其是BBS系統(tǒng))普及,越來(lái)越多的軟件依賴轉(zhuǎn)義序列起作用,導(dǎo)致幾乎所有新的終端和終端模擬器都支持了此標(biāo)準(zhǔn)。
1981年,ANSI X3.64被美國(guó)政府采用(FIPS 86)。后來(lái),美國(guó)政府停止復(fù)制行業(yè)標(biāo)準(zhǔn),所以FIPS 86又被撤回了。
ECMA-48已經(jīng)經(jīng)歷了多次更新?lián)Q代,當(dāng)前是從1991年開(kāi)始的第5版。它也被ISO和IEC用作標(biāo)準(zhǔn)ISO/IEC 6429。
支持平臺(tái)
隨著諸多BBS和線上服務(wù)廣泛使用ANSI,到20世紀(jì)80年代中期,ANSI幾乎得到了全平臺(tái)支持。盡管許多操作系統(tǒng)在標(biāo)準(zhǔn)文本輸出中越來(lái)越多地支持ANSI,但大多數(shù)情況下是以終端模擬器的形式(例如Unix上的xterm,或MacOS上的OS X Terminal或ZTerm,以及IBM PC上的許多通信程序)。
Unix和AmigaOS都在操作系統(tǒng)中包含了對(duì)ANSI的一些支持,導(dǎo)致在這些平臺(tái)上運(yùn)行的程序廣泛使用ANSI。 類Unix操作系統(tǒng)可以通過(guò)像termcap和curses之類的庫(kù)來(lái)生成ANSI代碼,許多軟件使用這些庫(kù)升級(jí)顯示方式。這些庫(kù)也應(yīng)該支持非ANSI終端,但是現(xiàn)在很少有人測(cè)試,所以很可能已經(jīng)不起作用了。許多游戲和shell腳本直接輸出ANSI序列(如彩色的提示信息),因此無(wú)法在不支持ANSI的終端上運(yùn)行。
AmigaOS不僅支持輸出到屏幕上的文本使用ANSI序列,打印機(jī)驅(qū)動(dòng)程序也支持(用AmigaOS的專有擴(kuò)展),并將它們轉(zhuǎn)換為與特定打印機(jī)實(shí)際通信所需的代碼。
盡管ANSI很普及,卻并沒(méi)有得到全平臺(tái)支持。比如原始的“經(jīng)典”Mac OS就沒(méi)有內(nèi)置對(duì)ANSI的支持,再比如Atari ST使用的是VT52改編的命令系統(tǒng),用一些擴(kuò)展程序支持顏色顯示。
MS-DOS 1.x不支持ANSI或任何其他轉(zhuǎn)義序列,只有少數(shù)控制字符(BEL、CR、LF、BS)可以由底層BIOS解釋,所以幾乎不可能做出任何全屏應(yīng)用程序。所有顯示效果都必須通過(guò)BIOS調(diào)用,或者直接控制IBM PC硬件來(lái)完成,調(diào)用速度非常慢。
DOS 2.0引入了添加設(shè)備驅(qū)動(dòng)程序來(lái)支持ANSI轉(zhuǎn)義序列的功能(事實(shí)上的標(biāo)準(zhǔn)是ANSI.SYS,但也使用了ANSI.COM、NANSI.SYS和ANSIPLUS.EXE等其他程序。因?yàn)槔@過(guò)了BIOS,所以這些程序的速度比以前快了不少)。但由于實(shí)際運(yùn)行速度仍然比較慢,以及默認(rèn)并沒(méi)有安裝,所以還是很少得到利用。應(yīng)用程序往往還是繼續(xù)用直接控制硬件的方式來(lái)顯示所需的文本。ANSI.SYS和類似的驅(qū)動(dòng)程序繼續(xù)在Windows 9x上工作,直到Windows Me,在NT派生系統(tǒng)中用于在NTVDM下執(zhí)行的16位傳統(tǒng)程序。
Win32控制臺(tái)完全不支持ANSI轉(zhuǎn)義序列。不過(guò)有一些控制臺(tái)的替代品或者附加軟件具有解釋程序輸出的ANSI轉(zhuǎn)義序列的功能,例如JP Software的TCC(以前的4NT)、Michael J. Mefford的ANSI.COM、Jason Hood的ANSICON和Maximus5的ConEmu。有一個(gè)Python軟件包在內(nèi)部解釋了打印文本中的ANSI轉(zhuǎn)義序列,將它們轉(zhuǎn)換為系統(tǒng)調(diào)用來(lái)操縱顏色和光標(biāo)位置,以便更容易地將使用ANSI的Python代碼移植到Windows。
2016年,在Windows 10發(fā)布“Threshold 2”時(shí),微軟開(kāi)始在控制臺(tái)應(yīng)用程序中支持ANSI轉(zhuǎn)義序列,使得從Unix移植軟件或者遠(yuǎn)程訪問(wèn)Unix變得更容易。
轉(zhuǎn)義序列
序列具有不同的長(zhǎng)度。所有序列都以ASCII字符ESC(十進(jìn)制的27 ,或十六進(jìn)制 0x1B,或八進(jìn)制的033,或轉(zhuǎn)義字符\e)開(kāi)頭,第二個(gè)字節(jié)則是0x40–0x5F(ASCII 的@A–Z[]^_)范圍內(nèi)的字符。
標(biāo)準(zhǔn)規(guī)定,在8位環(huán)境中,兩個(gè)字節(jié)的序列可以合并為0x80-0x9F范圍內(nèi)的單個(gè)字節(jié)(詳情請(qǐng)參閱C1控制字符集)。但是,在現(xiàn)代設(shè)備上,這些代碼通常用于其他目的,例如UTF-8的一部分或CP-1252字符,因此并不使用這種合并的方式。
除ESC之外的其他C0代碼(通常是BEL,BS,CR,LF,F(xiàn)F,TAB,VT,SO和SI)在輸出時(shí)也可能會(huì)產(chǎn)生與某些控制序列相似或相同的效果。
ANSI轉(zhuǎn)義序列C0列表
ANSI轉(zhuǎn)義序列C1不完整列表
按下鍵盤(pán)上的特殊鍵,或向終端輸出CSI、DCS或OSC請(qǐng)求序列,會(huì)產(chǎn)生從終端發(fā)送到計(jì)算機(jī)的CSI,DCS或OSC應(yīng)答序列,就像用戶使用鍵盤(pán)輸入的一樣。
CSI序列
ANSI轉(zhuǎn)義序列中以 ESC [
開(kāi)頭的叫作 Control Sequence Introducer
,簡(jiǎn)寫(xiě)為 CSI。
以 CSI 開(kāi)頭的指令有很多,大致可分四類:光標(biāo)移動(dòng)指令、清屏指令、字符渲染(Graphic Rendition)指令和終端控制指令。
CSI序列由ESC [、若干個(gè)(包括0個(gè))“參數(shù)字節(jié)”、若干個(gè)“中間字節(jié)”,以及一個(gè)“最終字節(jié)”組成。
各部分的字符范圍如下:
組成部分 | 字符范圍 | ASCII |
---|---|---|
參數(shù)字節(jié) | 0x30–0x3F | 0–9:;<=>? |
中間字節(jié) | 0x20–0x2F | 空格、!"#$%&’()*+,-./ |
最終字節(jié) | 0x40–0x7E | @A–Z[]^_`a–z{ |
所有常見(jiàn)的序列都只是把參數(shù)用作一系列分號(hào)分隔的數(shù)字,如1;2;3。缺少的數(shù)字視為0(如1;;3相當(dāng)于中間的數(shù)字是0,ESC[m這樣沒(méi)有參數(shù)的情況相當(dāng)于參數(shù)為0)。某些序列(如CUU)把0視為1,以使缺少參數(shù)的情況下有意義。
一部分字符定義是“私有”的,以便終端制造商可以插入他們自己的序列而不與標(biāo)準(zhǔn)相沖突。包括參數(shù)字節(jié)<=>?的使用,或者最終字節(jié)0x70–0x7F(p–z{|}~)例如VT320序列 CSI?25h
和 CSI?25l
的作用是打開(kāi)和關(guān)閉光標(biāo)的顯示。
當(dāng)CSI序列含有超出0x20–0x7E范圍的字符時(shí),其行為是未定義的。這些非法字符包括C0控制字符(范圍0–0x1F)、DEL(0x7F),以及高位字節(jié)。
一些CSI控制序列(不完整列表)
SGR
字符渲指令全稱 Select Graphic Rendition,簡(jiǎn)寫(xiě)為 SGR。
其格式為 CSI n m
,以數(shù)字開(kāi)頭,并以 m 結(jié)尾,n 的取值范圍是 0-107。
又可以分成兩類,一類控制字符顯示樣式,另一類控制顯示顏色。
SGR參數(shù)列表
顏色設(shè)置
3/4位色
初始的規(guī)格只有8種顏色,只給了它們的名字。SGR參數(shù)30-37選擇前景色,40-47選擇背景色。相當(dāng)多的終端將“粗體”(SGR代碼1)實(shí)現(xiàn)為更明亮的顏色而不是不同的字體,從而提供了8種額外的前景色,但通常情況下并不能用于背景色,雖然有時(shí)候反顯(SGR代碼7)可以允許這樣。
例如:
- 在白色背景上顯示黑色文字使用ESC[30;47m,
- 顯示紅色文字用ESC[31m,
- 顯示明亮的紅色文字用ESC[1;31m。
- 重置為默認(rèn)顏色用ESC[39;49m,
- 重置所有屬性用ESC[0m。
后來(lái)的終端新增了功能,可以直接用90-97和100-107指定“明亮”的顏色。當(dāng)硬件開(kāi)始使用8位DAC時(shí),多個(gè)軟件為這些顏色名稱分配了24位的代碼。下面的圖表顯示了發(fā)送到DAC的一些常用硬件和軟件的值。
8位色
隨著256色查找表在顯卡上越來(lái)越常見(jiàn),相應(yīng)的轉(zhuǎn)義序列也增加了,以從預(yù)定義的256種顏色中選擇:
- ESC[ … 38;5;n … m選擇前景色
- ESC[ … 48;5;n … m選擇背景色
- 0- 7:標(biāo)準(zhǔn)顏色(同ESC [ 30–37 m)
- 8- 15:高強(qiáng)度顏色(同ESC [ 90–97 m)
- 16-231:6 × 6 × 6 立方(216色): 16 + 36 × r + 6 × g + b (0 ≤ r, g, b ≤ 5)
- 232-255:從黑到白的24階灰度色
ITU的T.416信息技術(shù)-開(kāi)放文檔體系結(jié)構(gòu)(ODA)和交換格式:字符內(nèi)容體系結(jié)構(gòu)使用“:”作為分隔符:
- ESC[ … 38:5:n … m選擇前景色
- ESC[ … 48:5:n … m選擇背景色
24位色
隨著16位到24位顏色的“真彩色”顯卡的普及,Xterm、KDE的Konsole,以及所有基于libvte的終端(包括GNOME終端)支持了ISO-8613-3的24位前景色和背景色設(shè)置。
- ESC[ … 38;2;<r>;<g>;<b> … m選擇RGB前景色
- ESC[ … 48;2;<r>;<g>;<b> … m選擇RGB背景色
作為ISO / IEC國(guó)際標(biāo)準(zhǔn)8613-6采用的ITU的T.416信息技術(shù)-開(kāi)放文檔體系結(jié)構(gòu)(ODA)和交換格式:字符內(nèi)容體系結(jié)構(gòu)給出了一個(gè)似乎不太受支持的替代版本:
- ESC[ … 38:2:<Color-Space-ID>:<r>:<g>:<b>:<unused>:<CS tolerance>:<Color-Space: 0=“CIELUV”; 1=“CIELAB”>m選擇RGB前景色
- ESC[ … 48:2:<Color-Space-ID>:<r>:<g>:<b>:<unused>:<CS tolerance>:<Color-Space: 0=“CIELUV”; 1=“CIELAB”>m選擇RGB背景色
請(qǐng)注意,這里使用了保留的“:”字符來(lái)分隔子選項(xiàng),這可能是在實(shí)際實(shí)現(xiàn)中造成混淆的始作俑者。它還使用“3”作為第二個(gè)參數(shù)來(lái)指定使用青-品紅-黃方案的方案,“4”用于青-品紅-黃-黑的方案,后者使用上面標(biāo)記為“unused”的位置作為黑色組件。
還要注意,許多識(shí)別“:”作為分隔符的實(shí)現(xiàn)錯(cuò)誤地忽視了色彩空間標(biāo)識(shí)符參數(shù),并因此改變了其余部分的位置。
示例
- CSI 2 J — 清除屏幕、(在某些設(shè)備上)把光標(biāo)置于1,1位置(左上角)。
- CSI 32 m — 使文字呈綠色。在MS-DOS上,一般綠色是暗淡的綠色,可以用CSI 1 m啟用粗體使其變成明亮的綠色,或者將兩者合并為CSI 32 ; 1 m。MS-DOS ANSI.SYS用粗體狀態(tài)使字符變亮,閃爍狀態(tài)(通過(guò)INT 10, AX 1003h, BL 00h)使背景色變成明亮模式。MS-DOS ANSI.SYS并不直接支持SGR代碼90–97和100–107。
- CSI 0 ; 6 8 ; “DIR” ; 13 p — 重新分配F10鍵的功能為發(fā)送字符串“DIR”和回車符到鍵盤(pán)緩存中,在DOS命令行里會(huì)顯示當(dāng)前目錄的內(nèi)容(僅MS-DOS ANSI.SYS)。這種序列有時(shí)用于“ANSI炸彈”。這是一個(gè)私用編碼(如字母p所示),用非標(biāo)準(zhǔn)的擴(kuò)展使其包含一個(gè)字符串參數(shù)。如果按標(biāo)準(zhǔn),會(huì)認(rèn)為字母D是序列的末尾。
- CSI s — 保存光標(biāo)的位置。用序列CSI u會(huì)把光標(biāo)重置回這個(gè)位置。假設(shè)當(dāng)前的光標(biāo)位置是7(y)、10(x)。序列CSI s會(huì)保存這兩個(gè)數(shù)值?,F(xiàn)在可以把光標(biāo)移動(dòng)到其他位置,比如用序列CSI 20 ; 3 H或CSI 20 ; 3 f把光標(biāo)移動(dòng)到20(y)、3(x)?,F(xiàn)在如果用序列CSI u,光標(biāo)會(huì)回到7(y)、10(x)。某些終端需要使用DEC序列ESC 7/ESC 8,這得到了更廣泛的支持。
主要網(wǎng)址
xterm:https://invisible-island.net/xterm/
stackoverflow:https://stackoverflow.com/questions/4842424/list-of-ansi-color-escape-sequences
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
git如何從某個(gè)分支的指定歷史版本中創(chuàng)建新分支
這篇文章主要介紹了git如何從某個(gè)分支的指定歷史版本中創(chuàng)建新分支問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-05-05vscode配置leetcode插件并解決無(wú)法登錄問(wèn)題(圖文詳解)
這篇文章主要介紹了vscode配置leetcode插件并解決無(wú)法登錄問(wèn)題,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-06-06進(jìn)制轉(zhuǎn)換算法原理(二進(jìn)制 八進(jìn)制 十進(jìn)制 十六進(jìn)制)
進(jìn)制轉(zhuǎn)換算法原理(二進(jìn)制 八進(jìn)制 十進(jìn)制 十六進(jìn)制),以前上學(xué)那會(huì)確實(shí)學(xué)過(guò),長(zhǎng)時(shí)間不用都忘了。2010-05-05使用idea 去除 html 代碼前的行號(hào)和空行的方法詳解
這篇文章主要介紹了使用idea 去除 html 代碼前的行號(hào)和空行,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-07-07解決Fiddler在win7系統(tǒng)下的安全證書(shū)問(wèn)題
今天小編就為大家分享一篇關(guān)于解決Fiddler在win7系統(tǒng)下的安全證書(shū)問(wèn)題,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2018-10-10一不小心git rebase后出現(xiàn)(master|REBASE 1/10)的問(wèn)題及解決辦法
這篇文章主要介紹了一不小心git rebase后出現(xiàn)(master|REBASE 1/10)的問(wèn)題及解決辦法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-07-07計(jì)算機(jī)網(wǎng)絡(luò)日常練習(xí)題,每天進(jìn)步一點(diǎn)點(diǎn)
下面小編就為大家?guī)?lái)一篇計(jì)算機(jī)網(wǎng)絡(luò)的幾道練習(xí)題(分享)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧,希望可以幫到你2021-09-09Git回退(Revert)操作后無(wú)法重新合并的問(wèn)題及解決
這篇文章主要介紹了Git回退(Revert)操作后無(wú)法重新合并的問(wèn)題及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2025-04-04關(guān)于使用mvn deploy命令將本地jar包上傳到maven私服的問(wèn)題(收藏)
這篇文章主要介紹了使用mvn deploy命令將本地jar包上傳到maven私服,分享本篇教程可以幫助多數(shù)朋友少走彎路,本文具有很好的收藏價(jià)值,需要的朋友可以參考下2022-03-03