ANSI最全介绍linux终端字体改变颜色等

ANSI转义序列

维基百科,自由的百科全书

由于国内不能访问wiki而且国内关于ANSI的介绍都是简短的不能达到,不够完整所以转wiki到此博客,方便国内用户参考,原地址(https://zh.wikipedia.org/wiki/ANSI%E8%BD%AC%E4%B9%89%E5%BA%8F%E5%88%97

 

ANSI转义序列是一种带内信号英语In-band signaling转义序列标准,用于控制视频文本终端上的光标位置、颜色和其他选项。在文本中嵌入确定的字节序列,大部分以ESC转义字符和"["字符开始,终端会把这些字节序列解释为相应的指令,而不是普通的字符编码

ANSI序列是在二十世纪七十年代引入的标准,用以取代特定于终端供应商的序列,并在二十世纪八十年代早期开始在计算机设备市场上广泛使用。与早期缺少光标移动功能的系统相比,新生的电子公告板系统使用ANSI序列改进其显示。正是因为这个原因,ANSI序列变成了所有制造商共同采用的标准。

在21世纪,尽管硬件文本终端已经越来越少了,但ANSI标准依然存在,因为大多数终端模拟器会对部分ANSI转义序列进行解释。一个值得注意的例外是,在微软Windows 10更新TH2之前,Windows操作系统Win32控制台是不支持ANSI转义序列的。

历史

最初,几乎每个视频终端制造商都各自添加了特定的转义序列用于执行一些特殊操作,比如把光标置于屏幕上的某个位置。举例来说,VT52英语VT52终端允许通过发送ESC字符、y字符,后面跟上两个等于x,y位置的数值加上32的字符(这是为了从ASCII空格字符开始,并避开控制字符),将光标置于屏幕上的x,y位置。

由于这些序列对于不同的终端并不一样,因此人们不得不开发了一些复杂的库(比如termcap英语termcap)和实用程序(比如tput英语tput),以便程序可以使用同一套API应对各种终端。另外,在很多终端中需要借助字符的二进制值发送数字(如行和列)。对于某些编程语言,以及内部不使用ASCII的系统来说,把数字转换为正确的字符常常是有困难的,甚至完全做不到。

ANSI标准试图解决这些问题。标准制订了一种所有终端共享的指令集,并要求用ASCII的数字字符传递所有数值信息。该系列的第一个标准是1976年通过的ECMA-48。它是一系列字符编码标准的延续,其中第一个是从1965年的ECMA-6英语ECMA-6,一个7标准,ISO 646就源自此标准。“ANSI转义序列”的名称可以追溯到1979年ANSI采用ANSI X3.64。此外,ANSI X3L2委员会与ECMA委员会TC 1合作制订了一个几乎一模一样的标准。以上两个标准合并为ISO 6429的国际标准[1]。1994年,ANSI取消了其标准,以支持国际标准。

第一个支持这个标准的流行视频终端是1978年推出的Digital VT100英语VT100[2]。这个终端在市场上非常成功,引发了各种各样的仿制品,其中最早和最流行的是1979年的Zenith Z-19英语Zenith Z-89[3]。其他品牌还有Qume英语Qume QVT-108,Televideo英语Televideo TVI-970,Wyse英语Wyse WY-99GT。另外,许多其他品牌的终端也不同程度地兼容可选的“VT100”、“VT103”或“ANSI”模式。 随着越来越多的软件(尤其是BBS系统)普及,越来越多的软件依赖转义序列起作用,导致几乎所有新的终端和终端模拟器都支持了此标准。

1981年,ANSI X3.64被美国政府采用(FIPS 86)。后来,美国政府停止复制行业标准,所以FIPS 86又被撤回了[4]

ECMA-48已经经历了多次更新换代,当前是从1991年开始的第5版。它也被ISOIEC用作标准ISO/IEC 6429

平台支持

随着诸多BBS和线上服务广泛使用ANSI,到20世纪80年代中期,ANSI几乎得到了全平台支持。尽管许多操作系统在标准文本输出中越来越多地支持ANSI,但大多数情况下是以终端模拟器的形式(例如Unix上的xterm,或MacOS上的OS X TerminalZTerm英语ZTerm,以及IBM PC上的许多通信程序)。

UnixAmigaOS都在操作系统中包含了对ANSI的一些支持,导致在这些平台上运行的程序广泛使用ANSI。 类Unix操作系统可以通过像termcap英语termcapcurses库英语curses (programming library)之类的库来生成ANSI代码,许多软件使用这些库升级显示方式。这些库也应该支持非ANSI终端,但是现在很少有人测试,所以很可能已经不起作用了[来源请求]。许多游戏和shell脚本直接输出ANSI序列(如彩色的提示信息),因此无法在不支持ANSI的终端上运行。

AmigaOS不仅支持输出到屏幕上的文本使用ANSI序列,打印机驱动程序也支持(用AmigaOS的专有扩展),并将它们转换为与特定打印机实际通信所需的代码[5]

尽管ANSI很普及,却并没有得到全平台支持。比如原始的“经典”Mac OS就没有内置对ANSI的支持,再比如Atari ST使用的是VT52改编的命令系统,用一些扩展程序支持颜色显示[6]

Windows和DOS

MS-DOS 1.x不支持ANSI或任何其他转义序列,只有少数控制字符(BEL、CR、LF、BS)可以由底层BIOS解释,所以几乎[nb 1]不可能做出任何全屏应用程序。所有显示效果都必须通过BIOS调用,或者直接控制IBM PC硬件来完成,调用速度非常慢。

DOS 2.0引入了添加设备驱动程序来支持ANSI转义序列的功能(事实上的标准是ANSI.SYS,但也使用了ANSI.COM[7]、NANSI.SYS[8]和ANSIPLUS.EXE等其他程序。因为绕过了BIOS,所以这些程序的速度比以前快了不少)。但由于实际运行速度仍然比较慢,以及默认并没有安装,所以还是很少得到利用。应用程序往往还是继续用直接控制硬件的方式来显示所需的文本[来源请求]。ANSI.SYS和类似的驱动程序继续在Windows 9x上工作,直到Windows Me,在NT派生系统中用于在NTVDM英语NTVDM下执行的16位传统程序。

Win32控制台完全不支持ANSI转义序列。不过有一些控制台的替代品或者附加软件具有解释程序输出的ANSI转义序列的功能,例如JP Software的TCC(以前的4NT)、Michael J. Mefford的ANSI.COM、Jason Hood的ANSICON[9]和Maximus5的ConEmu。有一个Python软件包[10]在内部解释了打印文本中的ANSI转义序列,将它们转换为系统调用来操纵颜色和光标位置,以便更容易地将使用ANSI的Python代码移植到Windows。

2016年,在Windows 10发布“Threshold 2”[11]时,微软开始在控制台应用程序中支持ANSI转义序列,使得从Unix移植软件或者远程访问Unix变得更容易。

转义序列

序列具有不同的长度。所有序列都以ASCII字符ESC(27 / 十六进制 0x1B)开头,第二个字节则是0x40–0x5F(ASCII @A–Z[\]^_)范围内的字符。[12]:5.3.a

标准规定,在8位环境中,这两个字节的序列可以合并为0x80-0x9F范围内的单个字节(详情请参阅C1控制字符集)。但是,在现代设备上,这些代码通常用于其他目的,例如UTF-8的一部分或CP-1252字符,因此并不使用这种合并的方式。

除ESC之外的其他C0代码(通常是BEL,BS,CR,LF,FF,TAB,VT,SO和SI)在输出时也可能会产生与某些控制序列相似或相同的效果。

一些ANSI转义序列(不完整列表)
序 列C1名称作用
ESC N0x8eSS2 – Single Shift Two从其中一个替代字符集中选择一个字符。在xterm中,SS2选择G2字符集,SS3选择G3字符集。[13]
ESC O0x8fSS3 – Single Shift Three
ESC P0x90DCS – 设备控制字符串(Device Control String)控制设备。在xterm中,这个序列的使用包括定义用户自定义的密钥,以及请求或设置Termcap/Terminfo数据。[13]
ESC [0x9bCSI - 控制序列导入器(Control Sequence Introducer)大部分有用的序列,请参阅下一节。结束于ASCII 64到126 (@~/十六进制0x40到0x7E).[12]
ESC \0x9cST – 字符串终止(String Terminator)终止其他控件(包括APC,DCS,OSC,PM和SOS)中的字符串。[12]:8.3.143
ESC ]0x9dOSC – 操作系统命令(Operating System Command)启动操作系统使用的控制字符串。OSC序列与CSI序列相似,但不限于整数参数。通常,这些控制序列由ST终止[12]:8.3.89。在xterm中,它们也可能被BEL终止[13]。例如,在xterm中,窗口标题可以这样设置:OSC 0;this is the window title BEL
ESC X0x98SOS – 字符串开始(Start of String)引用由ST终止的一串文本的参数。这些字符串控制序列的用途由应用程序[12]:8.3.2,8.3.128或私有规则来定义[12]:8.3.94。这些函数没有实现,参数被xterm忽略[13]
ESC ^0x9ePM – 私有消息(Privacy Message)
ESC _0x9fAPC – 应用程序命令(Application Program Command)
ESC c RIS – 重置为初始状态(Reset to Initial State)将设备重置为原始状态。可能包括(如果适用的话):重置图形格式,清除制表符,重置为默认字体等等。

按下键盘上的特殊键,以及输出xterm CSI、DCS或OSC序列,常常用于产生从终端发送到计算机的CSI,DCS或OSC序列,就像用户使用键盘输入的一样。

 

CSI序列

CSI序列由ESC [、若干个(包括0个)“参数字节”、若干个“中间字节”,以及一个“最终字节”组成。各部分的字符范围如下:

CSI序列在ESC [之后各个组成部分的字符范围[12]:5.4
组成部分字符范围ASCII
参数字节0x30–0x3F0–9:;<=>?
中间字节0x20–0x2F空格、!"#$%&'()*+,-./
最终字节0x40–0x7E@A–Z[\]^_`a–z{|}~

所有常见的序列都只是把参数用作一系列分号分隔的数字,如1;2;3。缺少的数字视为0(如1;;3相当于中间的数字是0,ESC[m这样没有参数的情况相当于参数为0)。某些序列(如CUU)把0视为1,以使缺少参数的情况下有意义:F.4.2

一部分字符定义是“私有”的,以便终端制造商可以插入他们自己的序列而不与标准相冲突。包括参数字节<=>?的使用,或者最终字节0x70–0x7F(p–z{|}~)例如VT320英语VT320序列CSI?25hCSI?25l的作用是打开和关闭光标的显示。

当CSI序列含有超出0x20–0x7E范围的字符时,其行为是未定义的。这些非法字符包括C0控制字符(范围0–0x1F)、DEL(0x7F),以及高位字节。

一些ANSI控制序列(不完整列表)
代码名称作用

 

CSI n ACUU – 光标上移(Cursor Up)光标向指定的方向移动 n {\displaystyle n} n(默认1)格。如果光标已在屏幕边缘,则无效。

 

CSI n BCUD – 光标下移(Cursor Down)

 

CSI n CCUF – 光标前移(Cursor Forward)

 

CSI n DCUB – 光标后移(Cursor Back)
CSI n ECNL – 光标移到下一行(Cursor Next Line)光标移动到下面第 n {\displaystyle n} n(默认1)行的开头。(非ANSI.SYS英语ANSI.SYS
CSI n FCPL – 光标移到上一行(Cursor Previous Line)光标移动到上面第 n {\displaystyle n} n(默认1)行的开头。(非ANSI.SYS)
CSI n GCHA – 光标水平绝对(Cursor Horizontal Absolute)光标移动到第 n {\displaystyle n} n(默认1)列。(非ANSI.SYS)

 

CSI n ; m HCUP – 光标位置(Cursor Position)光标移动到第 n {\displaystyle n} n行、第 m {\displaystyle m} m列。值从1开始,且默认为1(左上角)。例如CSI ;5HCSI 1;5H含义相同;CSI 17;HCSI 17HCSI 17;1H三者含义相同。

 

CSI n JED – 擦除显示(Erase in Display)清除屏幕的部分区域。如果 n {\displaystyle n} n是0(或缺失),则清除从光标位置到屏幕末尾的部分。如果 n {\displaystyle n} n是1,则清除从光标位置到屏幕开头的部分。如果 n {\displaystyle n} n是2,则清除整个屏幕(在DOS ANSI.SYS中,光标还会向左上方移动)。如果 n {\displaystyle n} n是3,则清除整个屏幕,并删除回滚缓存区中的所有行(这个特性是xterm添加的,其他终端应用程序也支持)。

 

CSI n KEL – 擦除行(Erase in Line)清除行内的部分区域。如果 n {\displaystyle n} n是0(或缺失),清除从光标位置到该行末尾的部分。如果 n {\displaystyle n} n是1,清除从光标位置到该行开头的部分。如果 n {\displaystyle n} n是2,清除整行。光标位置不变。

 

CSI n SSU – 向上滚动(Scroll Up)整页向上滚动 n {\displaystyle n} n(默认1)行。新行添加到底部。(非ANSI.SYS)

 

CSI n TSD – 向下滚动(Scroll Down)整页向下滚动 n {\displaystyle n} n(默认1)行。新行添加到顶部。(非ANSI.SYS)

 

CSI n ; m fHVP – 水平垂直位置(Horizontal Vertical Position)同CUP。

 

CSI n mSGR – 选择图形再现(Select Graphic Rendition)设置SGR参数,包括文字颜色。CSI后可以是0或者更多参数,用分号分隔。如果没有参数,则视为CSI 0 m(重置/常规)。

 

CSI 5i打开辅助端口启用辅助串行端口,通常用于本地串行打印机

 

CSI 4i关闭辅助端口禁用辅助串行端口,通常用于本地串行打印机

 

CSI 6nDSR – 设备状态报告(Device Status Report)ESC[n;mR(就像在键盘上输入)向应用程序报告光标位置(CPR),其中 n {\displaystyle n} n是行, m {\displaystyle m} m是列。

 

CSI sSCP – 保存光标位置(Save Cursor Position)保存光标的当前位置。

 

CSI uRCP – 恢复光标位置(Restore Cursor Position)恢复保存的光标位置。

选择图形再现(SGR)参数

代码作用备注
0重置/正常关闭所有属性。
1粗体或增加强度 
2弱化(降低强度)未广泛支持。
3斜体未广泛支持。有时视为反相显示。
4下划线 
5缓慢闪烁低于每分钟150次。
6快速闪烁MS-DOS ANSI.SYS;每分钟150以上;未广泛支持。
7反显前景色与背景色交换。
8隐藏未广泛支持。
9划除字符清晰,但标记为删除。未广泛支持。
10主要(默认)字体 
11–19替代字体选择替代字体 n − 10 {\displaystyle n-10} {\displaystyle n-10}
20尖角体几乎无支持。
21关闭粗体或双下划线关闭粗体未广泛支持;双下划线几乎无支持。
22正常颜色或强度不强不弱。
23非斜体、非尖角体 
24关闭下划线去掉单双下划线。
25关闭闪烁 
27关闭反显 
28关闭隐藏 
29关闭划除 
30–37设置前景色参见下面的颜色表。
38设置前景色下一个参数是5;n2;r;g;b,见下。
39默认前景色由具体实现定义(按照标准)。
40–47设置背景色参见下面的颜色表。
48设置背景色下一个参数是5;n2;r;g;b,见下。
49默认背景色由具体实现定义(按照标准)。
51Framed 
52Encircled 
53上划线 
54Not framed or encircled 
55关闭上划线 
60表意文字下划线或右边线几乎无支持。
61表意文字双下划线或双右边线
62表意文字上划线或左边线
63表意文字双上划线或双左边线
64表意文字着重标志
65表意文字属性关闭重置6064的所有效果。
90–97设置明亮的前景色aixterm(非标准)。
100–107设置明亮的背景色aixterm(非标准)。

颜色

3/4位

初始的规格只有8种颜色,只给了它们的名字。SGR参数30-37选择前景色,40-47选择背景色。相当多的终端将“粗体”(SGR代码1)实现为更明亮的颜色而不是不同的字体,从而提供了8种额外的前景色,但通常情况下并不能用于背景色,虽然有时候反显(SGR代码7)可以允许这样。例如:在白色背景上显示黑色文字使用ESC[30;47m,显示红色文字用ESC[31m,显示明亮的红色文字用ESC[1;31m。重置为默认颜色用ESC[39;49m(某些终端不支持),重置所有属性用ESC[0m。后来的终端新增了功能,可以直接用90-97和100-107指定“明亮”的颜色。

当硬件开始使用8位DAC时,多个软件为这些颜色名称分配了24位的代码。下面的图表显示了发送到DAC的一些常用硬件和软件的值。[来源请求]

名称前景色代码背景色代码VGA[nb 2]CMD[nb 3]Terminal.appPuTTYmIRCxtermX英语X11 color names[nb 4]Ubuntu[nb 5]
30400,0,01,1,1
3141170,0,0128,0,0194,54,33187,0,0127,0,0205,0,0255,0,0222,56,43
绿32420,170,00,128,037,188,360,187,00,147,00,205,00,255,057,181,74
3343170,85,0[nb 6]128,128,0173,173,39187,187,0252,127,0205,205,0255,255,0255,199,6
34440,0,1700,0,12873,46,2250,0,1870,0,1270,0,238[14]0,0,2550,111,184
品红3545170,0,170128,0,128211,56,211187,0,187156,0,156205,0,205255,0,255118,38,113
36460,170,1700,128,12851,187,2000,187,1870,147,1470,205,2050,255,25544,181,233
3747170,170,170192,192,192203,204,205187,187,187210,210,210229,229,229255,255,255204,204,204
亮黑(灰)9010085,85,85128,128,128129,131,13185,85,85127,127,127127,127,127 128,128,128
亮红91101255,85,85255,0,0252,57,31255,85,85255,0,0255,0,0 255,0,0
亮绿9210285,255,850,255,049,231,3485,255,850,252,00,255,0144,238,1440,255,0
亮黄93103255,255,85255,255,0234,236,35255,255,85255,255,0255,255,0255,255,224255,255,0
亮蓝9410485,85,2550,0,25588,51,25585,85,2550,0,25292,92,255[15]173,216,2300,0,255
亮品红95105255,85,255255,0,255249,53,248255,85,255255,0,255255,0,255 255,0,255
亮青9610685,255,2550,255,25520,240,24085,255,2550,255,2550,255,255224,255,2550,255,255
亮白97107255,255,255255,255,255233,235,235255,255,255255,255,255255,255,255 255,255,255

8位

随着256色查找表在显卡上越来越常见,相应的转义序列也增加了,以从预定义的256种颜色中选择:[16]

   ESC[ … 38;5;<n> … m选择前景色
   ESC[ … 48;5;<n> … m选择背景色
     0-  7:标准颜色(同ESC [ 30–37 m)
     8- 15:高强度颜色(同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信息技术-开放文档体系结构(ODA)和交换格式:字符内容体系结构[17]使用“:”作为分隔符:

   ESC[ … 38:5:<n> … m选择前景色
   ESC[ … 48:5:<n> … m选择背景色
256色模式 — 前景色:ESC[38;5;#m   背景色:ESC[48;5;#m
标准色高强度色
 0  1  2  3  4  5  6  7   8  9 101112131415
216色
161718192021222324252627282930313233343536373839404142434445464748495051
525354555657585960616263646566676869707172737475767778798081828384858687
888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
灰度色
232233234235236237238239240241242243244245246247248249250251252253254255

24位[编辑]

随着16位到24位颜色的“真彩色”显卡的普及,Xterm[13]、KDE的Konsole[18],以及所有基于libvte的终端[19](包括GNOME终端英语GNOME Terminal)支持了ISO-8613-3的24位前景色和背景色设置。[16]

   ESC[ … 38;2;<r>;<g>;<b> … m选择RGB前景色
   ESC[ … 48;2;<r>;<g>;<b> … m选择RGB背景色

作为ISO / IEC国际标准8613-6采用的ITU的T.416信息技术-开放文档体系结构(ODA)和交换格式:字符内容体系结构[20]给出了一个似乎不太受支持的替代版本:

   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背景色

请注意,这里使用了保留的“:”字符来分隔子选项,这可能是在实际实现中造成混淆的始作俑者。它还使用“3”作为第二个参数来指定使用青-品红-黄方案的方案,“4”用于青-品红-黄-黑的方案,后者使用上面标记为“unused”(“未使用”)的位置作为黑色组件。

还要注意,许多识别“:”作为分隔符的实现错误地忽视了色彩空间标识符参数,并因此改变了其余部分的位置。

示例

CSI 2 J — 清除屏幕、(在某些设备上)把光标置于1,1位置(左上角)。

CSI 32 m — 使文字呈绿色。在MS-DOS上,一般绿色是暗淡的绿色,可以用CSI 1 m启用粗体使其变成明亮的绿色,或者将两者合并为CSI 32 ; 1 m。MS-DOS ANSI.SYS用粗体状态使字符变亮,闪烁状态(通过INT 10, AX 1003h, BL 00h)使背景色变成明亮模式。MS-DOS ANSI.SYS并不直接支持SGR代码90–97和100–107。

CSI 0 ; 6 8 ; "DIR" ; 13 p — 重新分配F10键的功能为发送字符串“DIR”和回车符到键盘缓存中,在DOS命令行里会显示当前目录的内容(仅MS-DOS ANSI.SYS)。这种序列有时用于“ANSI炸弹英语ANSI Bomb”。这是一个私用编码(如字母p所示),用非标准的扩展使其包含一个字符串参数。如果按标准,会认为字母D是序列的末尾。

CSI s — 保存光标的位置。用序列CSI u会把光标重置回这个位置。假设当前的光标位置是7(y)、10(x)。序列CSI s会保存这两个数值。现在可以把光标移动到其他位置,比如用序列CSI 20 ; 3 HCSI 20 ; 3 f把光标移动到20(y)、3(x)。现在如果用序列CSI u,光标会回到7(y)、10(x)。某些终端需要使用DEC序列ESC 7/ESC 8,这得到了更广泛的支持。

使用Shell脚本的示例[编辑]

ANSI转移代码常常用于UNIX和类UNIX终端,以提供语法高亮功能。例如,在兼容的终端上,以下ls命令按类型对文件和目录的名称进行颜色编码。

ls --color

用户可以在脚本中使用转义码,将其作为标准输出标准错误输出的一部分。例如,下面的GNU sed命令通过反显“WARN”开头的单词的行,以及使用暗红色背景色和亮黄色前景色显示以“ERR”开头的单词(字母大小写被忽略)的行来修饰make命令的输出。突出显示了设置ANSI代码的部分。[21]

make 2>&1 | sed -e 's/.*\bWARN.*/\x1b[7m&\x1b[0m/i' -e 's/.*\bERR.*/\x1b[93;41 m&\x1b[0m/i'

以下Bash函数会使终端闪烁(通过交替发送反相和正常显示模式代码),直到用户按下任意键[22]。这个函数可以用于当一个冗长的命令终止时提醒用户,用法如make; flasher[23]

flasher () { while true; do printf \\e[?5h; sleep 0.1; printf \\e[?5l; read -s -n1 -t1 && break; done; }

下面这个命令可以重置控制台,类似现代Linux系统的reset命令。然而,即使在较早的Linux系统和其他(非Linux)UNIX变体上,也应该能起作用。

printf \\033c

 

 
posted @ 2019-06-06 13:06 笔芯er 阅读( ...) 评论( ...) 编辑 收藏
Logo

更多推荐