如何在命令列中顯示五彩斑斕的“黑”

青筆發表於2019-10-07

1. 前言

大部分 coder 已經習慣了命令列枯燥的黑底白字,而且任何程式語言入門的第一行程式碼都是教我們如何在標準輸出(大部分情況就是命令列終端或控制檯)列印一行“非黑即白”的 hello world! 。以至於很多不懂程式設計的“大佬”都覺得程式猿們都TM奇了個葩了,整天對著一塊黑屏,瞎JB敲來敲去,還TM當個寶似的。那麼本文將告訴你,這不僅僅是一塊黑屏,它還能黑得五彩斑斕,亮瞎?眼。。。哈哈哈。。。下圖為本文最終能達到的效果,提前貼出來,以表示我沒有在吹?B。

如何在命令列中顯示五彩斑斕的“黑”

2. ANSI 轉義序列 (ANSI Escape sequences)

要在黑白電視機般的命令列終端顯示五彩斑斕的文字,就不得不先知道它的實現機制,即用於設定文字屬性和顏色的 ANSI 轉義序列

2.1 什麼是 ANSI 轉義序列 ?

ANSI 轉義序列有些地方也叫 ANSI 轉義碼(ANSI Escape codes)。它是由 ASCII 碼字元組成的序列,用於實現在命令列終端改變圖形顯示和控制游標移動。

它的前兩個字元固定是:

  • 轉義字元 Esc,ASCII 碼為 27 (十六進位制:0x1b)
  • 左中括號字元 [,ASCII 碼為 91 (十六進位制:0x5b)

後跟控制鍵盤和顯示功能的字母數字碼(區分大小寫)。這裡我們只討論與顯示相關的轉義序列,即設定圖形顯示模式。

2.2 使用 ANSI 轉義序列設定圖形顯示模式

格式(注意以字元m收尾):

Esc[Value;...;Valuem
複製程式碼

支援設定的顯示模式包含文字屬性,前景色和背景色。

2.2.1 文字屬性

Value 文字屬性
0 重置所有屬性
1 粗體顯示
4 下劃線
5 文字閃爍
7 反向顯示
8 隱藏

2.2.2 前景色

Value 顏色
30
31
32
33
34
35 品紅
36
37

2.2.3 背景色

Value 顏色
40
41
42
43
44
45 品紅
46
47

3. python 實現

理解了 ANSI 轉義序列的工作機制,使用任何程式語言都可以實現在命令列終端顯示不同顏色的文字和背景色。以 python 為例,一般我們使用 print() 函式,傳入字串,就會向標準輸出列印出熟悉的黑底白字,但如果在傳入的字串前加上控制顯示的 ANSI 轉義序列,就能按照我們設定的顯示模式來顯示了。

3.1 使用 print() 列印 ANSI 轉義序列

我們通過給 print() 傳入 ANSI 轉義序列 + 要顯示的字串 方式來控制文字的顯示模式。需要注意的是 ANSI 轉義序列 的第一個字元 Esc 是不可列印字元,我們需要以 unicode 轉義字元的形式表示, Esc 的 unicode 表示為 \u001b ; 此外,設定影像顯示模式,不要忘記了 ANSI 轉義序列 結尾處的字元 m,可以將 m 看做控制顯示模式的序列與要顯示文字的分隔符。

顯示紅色 "hello world!" :

print("\u001b[31m hello world!")
複製程式碼

如何在命令列中顯示五彩斑斕的“黑”

3.2 同時設定文字屬性+前景色+背景色

由前文圖形顯示模式的 ANSI 轉義序列 格式可以看出,支援一次設定多個 Value,多個 Value 用分號隔開。由於屬性,同一種顏色的前景和背景色 Value 都是不同的,所以他們設定的順序也沒有要求。例如,顯示綠底白字閃爍的“hello world!” 。

print("\u001b[42;37;5m hello world!")
複製程式碼

如何在命令列中顯示五彩斑斕的“黑”

3.3 重置所有屬性

細心的讀者應該注意到,在設定新的顯示屬性前,之前設定的屬性會一直保留,即使是命令列提示符也會受到影響。那麼為了每次設定的屬性隻影響當前的顯示,就需要在要顯示的文字後加上重置所有屬性的轉義序列 \u001b[0m

print("\u001b[34;1m hello world! \u001b[0m")

print("\u001b[41;37m hello \u001b[0m \u001b[32;4m world! \u001b[0m")
複製程式碼

如何在命令列中顯示五彩斑斕的“黑”

3.4 256 種顏色的擴充套件顏色集

前面介紹的不管是前景色還是背景色包含黑白兩色,也只有8種顏色,而且如果對審美有較高要求,這些顏色一點也不優雅。還好我們還有其他顏色可選,但只有部分終端支援。筆者只測試了 MacOs ,其他平臺的終端,讀者可以自行嘗試。

擴充套件顏色集轉義序列格式:

"\u001b[38;5;${ID}m"
複製程式碼

示例:

for i in range(0, 16):
    line = ""
    for j in range(0, 16):
        code = str(i * 16 + j)
        line += "\u001b[38;5;" + code + "m " + code.ljust(4)
    print(line)
    print("\u001b[0m")
複製程式碼

如何在命令列中顯示五彩斑斕的“黑”

當然也支援背景色,只需要將 38 改成 48:

"\u001b[48;5;${ID}m"
複製程式碼

示例:

for i in range(0, 16):
    line = ""
    for j in range(0, 16):
        code = str(i * 16 + j)
        line += "\u001b[48;5;" + code + "m " + code.ljust(4)
    print(line)
    print("\u001b[0m")
複製程式碼

如何在命令列中顯示五彩斑斕的“黑”

4. Nodejs 實現

參考 《nodejs 列印五彩斑斕的"黑"》

The End

命令列中顯示五彩斑斕的“黑”就是這麼簡單!

Thanks

如果本文對你有幫助,請不要吝惜點贊哦 ?

【閱讀原文】

如何在命令列中顯示五彩斑斕的“黑”
微信掃描二維碼 獲取最新技術原創

相關文章