1. 程式人生 > >通過printf設定Linux終端輸出的顏色和顯示方式

通過printf設定Linux終端輸出的顏色和顯示方式

前言

     在Linux終端下除錯程式時,有時需要輸出大量資訊。若能控制字型的顏色和顯示方式,可使輸出資訊對比鮮明,便於除錯時觀察資料。

     終端的字元顏色由轉義序列(Escape Sequence)控制,是文字模式下的系統顯示功能,與具體語言無關。

     本文簡要介紹C語言中通過printf改變終端輸出的顏色和顯示方式。文中涉及的程式碼執行環境如下:

 

 

正文

     轉義序列以控制字元'ESC'開頭。該字元的ASCII碼十進位制表示為27,十六進位制表示為0x1B,八進位制表示為033。多數轉義序列超過兩個字元,故通常以'ESC'和左括號'['開頭。該起始序列稱為控制序列引導符(CSI,Control Sequence Intro),通常由'\033['或'\e['代替。

     通過轉義序列設定終端顯示屬性時,可採用以下格式:

\033[ Param {;Param;...}m

\e[ Param {;Param;...}m

     其中,'\033['或'\e['引導轉義序列,'m'表示設定屬性並結束轉義序列。Param為屬性值,{...}表示可選(多個引數之間用分號隔開,與順序無關)。例如,在Linux Shell中執行下述命令:

     即設定輸出為紅色字型(31),白色背景(47)。選項'-e'為echo命令啟用特殊字元的解析器。

     注意,轉義序列可被控制字元'CAN'(Cancel )和'SUB'(Substitute)中斷。

     轉義序列相關的常用引數如下(通過man console_codes命令可檢視更多的引數描述):

  • 顯示:0(預設)、1(粗體/高亮)、22(非粗體)、4(單條下劃線)、24(無下劃線)、5(閃爍)、25(無閃爍)、7(反顯、翻轉前景色和背景色)、27(無反顯)
  • 顏色:0(黑)、1(紅)、2(綠)、 3(黃)、4(藍)、5(洋紅)、6(青)、7(白)

     前景色為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系列語句:

#define NONE                 "\e[0m"
#define BLACK                "\e[0;30m"
#define L_BLACK              "\e[1;30m"
#define RED                  "\e[0;31m"
#define L_RED                "\e[1;31m"
#define GREEN                "\e[0;32m"
#define L_GREEN              "\e[1;32m"
#define BROWN                "\e[0;33m"
#define YELLOW               "\e[1;33m"
#define BLUE                 "\e[0;34m"
#define L_BLUE               "\e[1;34m"
#define PURPLE               "\e[0;35m"
#define L_PURPLE             "\e[1;35m"
#define CYAN                 "\e[0;36m"
#define L_CYAN               "\e[1;36m"
#define GRAY                 "\e[0;37m"
#define WHITE                "\e[1;37m"

#define BOLD                 "\e[1m"
#define UNDERLINE            "\e[4m"
#define BLINK                "\e[5m"
#define REVERSE              "\e[7m"
#define HIDE                 "\e[8m"
#define CLEAR                "\e[2J"
#define CLRLINE              "\r\e[K" //or "\e[1K\r"

     編寫測試程式碼驗證轉義序列控制的效果:

int main(void)
{
    printf("This is a character control test!\n" );
    sleep(3);
    printf("[%2u]" CLEAR "CLEAR\n" NONE, __LINE__);

    printf("[%2u]" BLACK "BLACK " L_BLACK "L_BLACK\n" NONE, __LINE__);
    printf("[%2u]" RED "RED " L_RED "L_RED\n" NONE, __LINE__);
    printf("[%2u]" GREEN "GREEN " L_GREEN "L_GREEN\n" NONE, __LINE__);
    printf("[%2u]" BROWN "BROWN " YELLOW "YELLOW\n" NONE, __LINE__);
    printf("[%2u]" BLUE "BLUE " L_BLUE "L_BLUE\n" NONE, __LINE__);
    printf("[%2u]" PURPLE "PURPLE " L_PURPLE "L_PURPLE\n" NONE, __LINE__);
    printf("[%2u]" CYAN "CYAN " L_CYAN "L_CYAN\n" NONE, __LINE__);
    printf("[%2u]" GRAY "GRAY " WHITE "WHITE\n" NONE, __LINE__);

    printf("[%2u]\e[1;31;40m Red \e[0m\n",  __LINE__);

    printf("[%2u]" BOLD "BOLD\n" NONE, __LINE__);
    printf("[%2u]" UNDERLINE "UNDERLINE\n" NONE, __LINE__);
    printf("[%2u]" BLINK "BLINK\n" NONE, __LINE__);
    printf("[%2u]" REVERSE "REVERSE\n" NONE, __LINE__);
    printf("[%2u]" HIDE "HIDE\n" NONE, __LINE__);

    printf("Cursor test begins!\n" );
    printf("=======!\n" );
    sleep(10);
    printf("[%2u]" "\e[2ACursor up 2 lines\n" NONE, __LINE__);
    sleep(10);
    printf("[%2u]" "\e[2BCursor down 2 lines\n" NONE, __LINE__);
    sleep(5);
    printf("[%2u]" "\e[?25lCursor hide\n" NONE, __LINE__);
    sleep(5);
    printf("[%2u]" "\e[?25hCursor display\n" NONE, __LINE__);
    sleep(5);

    printf("Test ends!\n" );
    sleep(3);
    printf("[%2u]" "\e[2ACursor up 2 lines\n" NONE, __LINE__);
    sleep(5);
    printf("[%2u]" "\e[KClear from cursor downward\n" NONE, __LINE__);

    return 0 ;
}

     執行結果截圖如下:

     因截圖所限,未能展示閃爍和游標移動等效果。

     注意,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):