1 前言
在Windows系统中,我们可以通过系统提供的接口操作控制台缓冲区的显示。那么在linux平台应该如何实现呢?答案就是ANSI转义序列。
在计算机系统中,ANSI转义码(或转义序列)是一种使用带内信号控制视频文本终端的格式、颜色和其他输出选项的方法。
为了编码这种格式化信息,特定的字节序列被嵌入到文本中,终端将查找并将其解释为命令,而不是字符代码。
2 CSI
实际上,ANSI转义序列的范围比较大,包括ASCII码表中的被称为Control characters 控制字符(C0代码)之外,还包括了ESC字符开头的C1代码。
而这里介绍的就是C1代码中最常用的部分CSI序列。
ANSI转义序列中以 ESC [
开头的叫作 Control Sequence Introducer
,简写为 CSI。
以 CSI 开头的指令有很多,大致可分四类:光标控制、屏幕控制、和字符渲染(Graphic Rendition)指令。
CSI序列的语法如下所示:
0x1B + "[" + [[0-9]*[;]] + <fun>
- 开始,
0x1B
是ansi escape code开始的标准 - 其次,
[
是CSI (Control Sequence Introducer) - 然后,中间部分由0个或者多个数字组成,是函数的参数,多个参数之间由分号进行分割。
- 最终,一个字母代表需要调用的函数名
CSI (Control Sequence Introducer) 各部分的字符范围如下:
组成部分 | 字符范围 | ASCII |
---|---|---|
参数字节 | 0x30–0x3F | 0–9:;<=>? |
中间字节 | 0x20–0x2F | 空格、!"#$%&’()*+,-./ |
最终字节 | 0x40–0x7E | @A–Z[]^_`a–z{ |
2.1 光标控制
控制码 | 说明 |
---|---|
\033[nA | 光标上移 n(默认1) 行 <<若至屏幕顶端则无效>> |
\033[nB | 光标下移 n (默认1)行 <<若至屏幕底端则无效>> |
\033[nC | 光标前移 n (默认1)列 <<若至屏幕右端则无效>> |
\033[nD | 光标后退 n (默认1)列 <<若至屏幕左端则无效>> |
\033[nE | 光标下移 n (默认1)行 <<非标准>> |
\033[nF | 光标上移 n (默认1)行 <<非标准>> |
\033[nG | 光标移动至当前行n(默认1)列 <<非标准>> |
\033[x;yH | 光标移动至x行y列(默认从1开始,左上角) |
\033[s | 保存光标位置 |
\033[u | 取出保存的光标位置来使用 |
\033[?25l | 隐藏光标 |
\033[?25h | 显示光标 |
2.2 屏幕控制
控制码 | 说明 |
---|---|
\033[nJ | 清除指定范围屏幕。0:光标位置至屏幕末尾;1:光标位置至屏幕开头;2:全屏幕 |
\033[nK | 擦除行中指定范围列。0:光标位置至行尾;1:光标位置至行头;2:整行 |
\033[nS | 整页向上滚动n行。<<非标准>> |
\033[nT | 整页向下滚动n行。<<非标准>> |
2.3 字符渲染
字符渲指令全称 Select Graphic Rendition
,简写为 SGR。其格式为 CSI n m
,以数字开头,并以 m 结尾,n 的取值范围是 0-107。又可以分成两类,一类控制字符显示样式,另一类控制显示颜色。
代码 | 含义 |
---|---|
0 | 所有属性 OFF,即返回正常显示模式 (Normal) |
1 | 粗体(Bold)/高亮度显示 (Bright) |
3 | 斜体(未广泛支持) |
4 | 下划线 |
5 | 闪烁显示 |
7 | 反显(前景色与背景色交换) |
39 | 默认前景色 |
49 | 默认背景色 |
设置颜色:文章来源:https://www.toymoban.com/news/detail-728477.html
前景 | 背景 | 颜色 |
---|---|---|
30 | 40 | 黑色 |
31 | 41 | 红色 |
32 | 42 | 绿色 |
33 | 43 | 黄色 |
34 | 44 | 蓝色 |
35 | 45 | 紫红色 |
36 | 46 | 青蓝色 |
37 | 47 | 白色 |
3 示例
3.1 清除屏幕
printf("\x1b[2J"); // 清屏幕
printf("\x1b[?25l"); // 设置光标不可见
3.2 禁用回显
struct termios setting;
tcgetattr(STDIN_FILENO, &setting); // 禁用回显
setting.c_lflag &= ~ECHO;
tcsetattr(STDIN_FILENO, TCSANOW, &setting);
3.3 获取标准输入
fd_set io;
FD_SET(STDIN_FILENO, &io);
timeval timeout = {sec, usec};
select(STDIN_FILENO + 1, &io, NULL, NULL, &timeout); // 监听标准输入
char cmd[10] = {0};
read(STDIN_FILENO, cmd, sizeof(cmd)); // read读取标准输入避免循环getc阻塞
3.4 数据输出到屏幕
printf("\x1b[2;1H"); // 光标定位至第二行开头
printf("\x1b[30;47m"); // 设置白底黑字
fill(header, strlen(header)); // 输出
printf("\x1b[39;49m"); // 设置默认颜色
// 光标移动至指定行的行首
void move(int y) { printf("\x1b[%d;1H", y); }
// 输出字符串同时清除光标后的列
void print(const char* str) { printf("%s\x1b[K", str); }
4 完整示例
平台实现简单的进程信息查看。simple_taskmgr文章来源地址https://www.toymoban.com/news/detail-728477.html
到了这里,关于Linux终端控制与ANSI转义序列的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!