在Linux終端下調試程序時,有時須要輸出大量信息。若能控制字體的顏色和顯示方式,可以使輸出信息對比鮮明,便於調試時觀察數據。ide
終端的字符顏色由轉義序列(Escape Sequence)控制,是文本模式下的系統顯示功能,與具體語言無關。工具
本文簡要介紹C語言中經過printf改變終端輸出的顏色和顯示方式。文中涉及的代碼運行環境以下:測試
轉義序列以控制字符'ESC'開頭。該字符的ASCII碼十進制表示爲27,十六進制表示爲0x1B,八進制表示爲033。多數轉義序列超過兩個字符,故一般以'ESC'和左括號'['開頭。該起始序列稱爲控制序列引導符(CSI,Control Sequence Intro),一般由'\033['或'\e['代替。字體
經過轉義序列設置終端顯示屬性時,可採用如下格式:spa
\033[ Param {;Param;...}m3d 或調試 \e[ Param {;Param;...}mcode |
其中,'\033['或'\e['引導轉義序列,'m'表示設置屬性並結束轉義序列。Param爲屬性值,{...}表示可選(多個參數之間用分號隔開,與順序無關)。例如,在Linux Shell中執行下述命令:blog
即設置輸出爲紅色字體(31),白色背景(47)。選項'-e'爲echo命令激活特殊字符的解析器。ci
注意,轉義序列可被控制字符'CAN'(Cancel )和'SUB'(Substitute)中斷。
轉義序列相關的經常使用參數以下(經過man console_codes命令可查看更多的參數描述):
前景色爲30+顏色值,如31表示前景色爲紅色;背景色爲40+顏色值,如41表示背景色爲紅色。
調色效果以下圖所示:
所以,經過轉義序列設置終端顯示屬性時,常見格式爲:
\033[顯示方式;前景色;背景色m輸出字符串\033[0m 或 \e[顯示方式;前景色;背景色m輸出字符串\033[0m |
其中 ,'\033[0m'用於恢復默認的終端輸出屬性,不然會影響後續的輸出。
此外,還有一些ANSI控制碼,如:nA (光標上移n行 )、nB(光標下移n行 )、nC(光標右移n行 )、nD (光標左移n行 )、2J(清屏)、K(清除從光標到行尾的內容)、s(保存光標位置)、u(恢復光標位置)、?25l(隱藏光標)、?25l(顯示光標)。
基於經常使用參數,可定義以下單一控制宏,用於printf系列語句:
1 #define NONE "\e[0m" 2 #define BLACK "\e[0;30m" 3 #define L_BLACK "\e[1;30m" 4 #define RED "\e[0;31m" 5 #define L_RED "\e[1;31m" 6 #define GREEN "\e[0;32m" 7 #define L_GREEN "\e[1;32m" 8 #define BROWN "\e[0;33m" 9 #define YELLOW "\e[1;33m" 10 #define BLUE "\e[0;34m" 11 #define L_BLUE "\e[1;34m" 12 #define PURPLE "\e[0;35m" 13 #define L_PURPLE "\e[1;35m" 14 #define CYAN "\e[0;36m" 15 #define L_CYAN "\e[1;36m" 16 #define GRAY "\e[0;37m" 17 #define WHITE "\e[1;37m" 18 19 #define BOLD "\e[1m" 20 #define UNDERLINE "\e[4m" 21 #define BLINK "\e[5m" 22 #define REVERSE "\e[7m" 23 #define HIDE "\e[8m" 24 #define CLEAR "\e[2J"
25 #define CLRLINE "\r\e[K" //or "\e[1K\r"
編寫測試代碼驗證轉義序列控制的效果:
1 int main(void) 2 { 3 printf("This is a character control test!\n" ); 4 sleep(3); 5 printf("[%2u]" CLEAR "CLEAR\n" NONE, __LINE__); 6 7 printf("[%2u]" BLACK "BLACK " L_BLACK "L_BLACK\n" NONE, __LINE__); 8 printf("[%2u]" RED "RED " L_RED "L_RED\n" NONE, __LINE__); 9 printf("[%2u]" GREEN "GREEN " L_GREEN "L_GREEN\n" NONE, __LINE__); 10 printf("[%2u]" BROWN "BROWN " YELLOW "YELLOW\n" NONE, __LINE__); 11 printf("[%2u]" BLUE "BLUE " L_BLUE "L_BLUE\n" NONE, __LINE__); 12 printf("[%2u]" PURPLE "PURPLE " L_PURPLE "L_PURPLE\n" NONE, __LINE__); 13 printf("[%2u]" CYAN "CYAN " L_CYAN "L_CYAN\n" NONE, __LINE__); 14 printf("[%2u]" GRAY "GRAY " WHITE "WHITE\n" NONE, __LINE__); 15 16 printf("[%2u]\e[1;31;40m Red \e[0m\n", __LINE__); 17 18 printf("[%2u]" BOLD "BOLD\n" NONE, __LINE__); 19 printf("[%2u]" UNDERLINE "UNDERLINE\n" NONE, __LINE__); 20 printf("[%2u]" BLINK "BLINK\n" NONE, __LINE__); 21 printf("[%2u]" REVERSE "REVERSE\n" NONE, __LINE__); 22 printf("[%2u]" HIDE "HIDE\n" NONE, __LINE__); 23 24 printf("Cursor test begins!\n" ); 25 printf("=======!\n" ); 26 sleep(10); 27 printf("[%2u]" "\e[2ACursor up 2 lines\n" NONE, __LINE__); 28 sleep(10); 29 printf("[%2u]" "\e[2BCursor down 2 lines\n" NONE, __LINE__); 30 sleep(5); 31 printf("[%2u]" "\e[?25lCursor hide\n" NONE, __LINE__); 32 sleep(5); 33 printf("[%2u]" "\e[?25hCursor display\n" NONE, __LINE__); 34 sleep(5); 35 36 printf("Test ends!\n" ); 37 sleep(3); 38 printf("[%2u]" "\e[2ACursor up 2 lines\n" NONE, __LINE__); 39 sleep(5); 40 printf("[%2u]" "\e[KClear from cursor downward\n" NONE, __LINE__); 41 42 return 0 ; 43 }
執行結果截圖以下:
因截圖所限,未能展現閃爍和光標移動等效果。
注意,Linux終端下可正常顯示彩色字符。但若經過SecureCRT等Windows工具SSH登陸Linux主機,則需對工具作些設置。
以SecureCRT 6.6爲例,在Options->Session Options->Terminal->Emulation頁的Terminal類型中選擇ANSI或Linux或Xterm,並勾選ANSI Color。
而後,在Appearance頁中選擇顏色方案爲Windows或Traditional。爲突出測試代碼中的輸出顏色,此處選擇Windows方案(須要在Emulation頁勾選Use color scheme):