Linux终端彩色打印+终端进度条【转】

简介: 转自:https://my.oschina.net/jcseg/blog/178047 开发的一个应用程序选择了终端界面, 为了使软件稍微好看些, 研究下Linux终端的彩色打印, 并且基于这个彩色打印实现了几种进度条, 在此总结下: (更多的是觉得这个东西挺好玩的.

转自:https://my.oschina.net/jcseg/blog/178047

开发的一个应用程序选择了终端界面, 为了使软件稍微好看些, 研究下Linux终端的彩色打印, 并且基于这个彩色打印实现了几种进度条, 在此总结下: (更多的是觉得这个东西挺好玩的... )

一. Linux终端色彩打印:

1. 属性介绍: 

(1). 来自网络的ANSI属性控制码: 

\033[0m                 关闭所有属性
\033[1m                 设置高亮度
\033[4m                 下划线 \033[5m                 闪烁 \033[7m                 反显 \033[8m                 消隐 \033[30m -- \033[37m    设置前景色 \033[40m -- \033[47m    设置背景色 \033[nA                 光标上移n行 \033[nB                 光标下移n行 \033[nC                 光标右移n列 \033[nD                 光标左移n列 \033[y;H                设置光标位置 \033[2J                 清屏 \033[K                  清除从光标到行尾的内容 \033[s                  保存光标位置 \033[u                  恢复光标位置 \033[?25l               隐藏光标 \033[?25h               显示光标

(2). 文字背景色彩数字: (颜色范围:40 - 49)

40:    黑色
41:    深红色
42:    绿色
43:    黄色
44:    蓝色
45:    紫色
46:    深绿色
47:    白色

(3). 文字前景色数字: (颜色范围: 30 - 39)

30:    黑色
31:    红色
32:    绿色
33:    黄色
34:    蓝色
35:    紫色
36:    深绿色
37:    白色

2. 使用例子:

Linux终端会解析这些控制码, 并且依据控制码来设置终端的绘制属性, 所以, 只要输出流中包含ANSI控制码就可以工作, 这里使用linux的echo命令来演示:  (你可以使用任何你熟悉的语言来代替...)

(1). 字体红色输出:   

查看上面的ANSI控制码可以知道: \033[30m -- \033[37m是控制前景色, 并且红色使用31表示, 即: 红色ANSI控制码为:  \033[31m

echo -e "\33[31m红色字体\33[0m"     #需要加上-e参数

 

从\033[31m处开始使用"红色"作为字体的前景色, 后面全部的绘制都使用红色, 直到遇到属性关闭控制码. 所以: 后面使用\033[0m来关闭属性, 要不然终端后面的输入的文字将全部是红色的. 效果图:

(2). 使用多个控制码产生叠加效果:  红色+高亮

echo -e "\033[31m\033[1m红色+高亮\033[0m"   #高亮控制码为: \033[1m

效果:

(3). 红底+白字+高亮+下划线:

 

echo -e "\033[41m\033[37m\033[1m\033[4m红底+白字+高亮+下划线\033[0m"

效果:

多个控制码可以一起使用, 从而看到叠加的效果, 控制码之间的顺序无所谓, 例如: 上面的高亮和下划线.  其他的控制码就可以自己试试了.

 

二. Linux终端进度条的实现:

了解了上面的Linux终端彩色打印, 就可以开始做出漂亮的终端进度条了.

 1. 利用\r backspace符来制作进度条:

(1). 一个php例子如下:  (注意, php要使用printf, echo没用的)

<?php for ($i = 0; $i <= 50; $i++) { printf("mprogress: %d%% %s\r", $i * 2, str_repeat('#',$i) ); usleep(1000 * 100); } echo "\n", "Done.\n"; ?>

运行效果如下:

(2). 加上色彩:

(3). 进一步美化, 使用背景并且使用空格代替'#'字符:

<?php for ($i = 0; $i <= 50; $i++) { printf("mprogress: \033[41m\033[1m %d%% %s\r\033[0m", $i * 2, str_repeat(' ',$i) ); usleep(1000 * 100); } echo "\n", "Done.\n"; ?>

效果:

哈, 效果还不错呢.

(4). 终极美化, 将光标隐藏:

这个只要在里面加上隐藏光标的ANSI控制码就ok了, 不过记得要在后面将光标回复显示, 要不然后面终端就看不到光标了:

<?php
for ($i = 0; $i <= 50; $i++) {
  printf("\033[?25lmprogress: \033[41m\033[1m %d%% %s\r\033[0m", $i * 2, str_repeat(' ',$i) ); usleep(1000 * 100); } printf("\nDone.\n\033[?25h"); ?>

 

效果:

到此Linux终端进度条制作完毕.

 

三. 一个C的进度条封装: 

1. progress.h头文件: 

/**
 * linux terminal progress bar (no thread safe).
 * 	@package progress.h.
 *
 * @author chenxin <chenxin619315@gmail.com>
 */
#ifndef progress_h #define progress_h #include <stdio.h> typedef struct { char chr; /*tip char*/ char *title; /*tip string*/ int style; /*progress style*/ int max; /*maximum value*/ float offset; char *pro; } progress_t; #define PROGRESS_NUM_STYLE 0 #define PROGRESS_CHR_STYLE 1 #define PROGRESS_BGC_STYLE 2 extern void progress_init(progress_t *, char *, int, int); extern void progress_show(progress_t *, float); extern void progress_destroy(progress_t *); #endif /*ifndef*/

 

 

2. progress.c 源程序:

/**
 * linux terminal progress bar (no thread safe).
 * 	@package progress.c
 *
 * @author chenxin <chenxin619315@gmail.com>
 */
#include <stdio.h> #include <stdlib.h> #include <string.h> #include "progress.h" /** * initialize the progress bar. * @max = 0 * @val = 0 * * @param style * @param tip words. */ extern void progress_init( progress_t *bar, char *title, int max, int style) { bar->chr = '#'; bar->title = title; bar->style = style; bar->max = max; bar->offset = 100 / (float)max; bar->pro = (char *) malloc(max+1); if ( style == PROGRESS_BGC_STYLE ) memset(bar->pro, 0x00, max+1); else { memset(bar->pro, 32, max); memset(bar->pro+max, 0x00, 1); } } extern void progress_show( progress_t *bar, float bit ) { int val = (int)(bit * bar->max); switch ( bar->style ) { case PROGRESS_NUM_STYLE: printf("\033[?25l\033[31m\033[1m%s%d%%\033[?25h\033[0m\r", bar->title, (int)(bar->offset * val)); fflush(stdout); break; case PROGRESS_CHR_STYLE: memset(bar->pro, '#', val); printf("\033[?25l\033[31m\033[1m%s[%-s] %d%%\033[?25h\033[0m\r", bar->title, bar->pro, (int)(bar->offset * val)); fflush(stdout); break; case PROGRESS_BGC_STYLE: memset(bar->pro, 32, val); printf("\033[?25l\033[31m\033[1m%s\033[41m %d%% %s\033[?25h\033[0m\r", bar->title, (int)(bar->offset * val), bar->pro); fflush(stdout); break; } } //destroy the the progress bar. extern void progress_destroy(progress_t *bar) { free(bar->pro); }

 

 

3. tst-pro.c测试程序:

/**
 * program bar test program.
 *
 * @author chenxin <chenxin619315@gmail.com>
 */
#include "progress.h" #include <unistd.h> int main(int argc, char *argv[] ) { progress_t bar; //progress_init(&bar, "", 50, PROGRESS_NUM_STYLE); progress_init(&bar, "", 50, PROGRESS_CHR_STYLE); //progress_init(&bar, "", 50, PROGRESS_BGC_STYLE); int i; for ( i = 0; i <= 50; i++ ) { progress_show(&bar, i/50.0f); sleep(1); } printf("\n+-Done\n"); progress_destroy(&bar); return 0; }

 

 

4. 测试效果: 

(1). PROGRESS_NUM_STYLE效果:

(2). PROGRESS_CHR_STYLE效果:

(3). PROGRESS_BGC_STYLE效果:

完毕. 代码托管到: http://git.oschina.net/lionsoul/ltpro

【作者】 张昺华
【新浪微博】 张昺华--sky
【twitter】 @sky2030_
【facebook】 张昺华 zhangbinghua
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
目录
相关文章
|
2月前
|
安全 Shell Linux
【Shell 命令集合 系统管理 】Linux 锁定终端 vlock命令 使用指南
【Shell 命令集合 系统管理 】Linux 锁定终端 vlock命令 使用指南
37 1
|
2月前
|
缓存 IDE Shell
【Shell 命令集合 系统设置 】Linux 重置终端的显示 reset命令 使用指南
【Shell 命令集合 系统设置 】Linux 重置终端的显示 reset命令 使用指南
41 0
|
2月前
|
Unix Shell Linux
Linux 终端和进程的关系,以及在终端前后台切换进程
Linux 终端和进程的关系,以及在终端前后台切换进程
40 1
|
2月前
|
缓存 小程序 Linux
【Linux】Linux第一个小程序-进度条
【Linux】Linux第一个小程序-进度条
|
2月前
|
小程序 Linux 开发工具
Linux:进度条(小程序)以及git三板斧
Linux:进度条(小程序)以及git三板斧
35 2
|
2月前
|
Shell Linux C语言
【Shell 命令集合 系统设置 】⭐⭐⭐Linux 清除终端屏幕内容 clear命令 使用指南
【Shell 命令集合 系统设置 】⭐⭐⭐Linux 清除终端屏幕内容 clear命令 使用指南
40 0
|
2月前
|
Shell Linux C语言
【Shell 命令集合 网络通讯 】Linux 向指定用户或终端发送消息 write命令 使用指南
【Shell 命令集合 网络通讯 】Linux 向指定用户或终端发送消息 write命令 使用指南
41 0
|
2月前
|
监控 Linux Shell
【Shell 命令集合 网络通讯 】Linux管理终端设备的登录过程 getty命令 使用指南
【Shell 命令集合 网络通讯 】Linux管理终端设备的登录过程 getty命令 使用指南
37 0
|
2月前
|
安全 Shell Linux
【Shell 命令集合 网络通讯 】Linux 打开终端设备 mingetty命令 使用指南
【Shell 命令集合 网络通讯 】Linux 打开终端设备 mingetty命令 使用指南
45 0
|
4天前
|
Linux Shell
Linux 终端入门
Linux 终端入门