目录
介绍
终端的默认文本输出是单色的,并且不提供提供上下文的简单方法。例如,您可能希望错误以红色显示,成功以绿色显示,或者重要信息以粗体显示。
为终端输出添加颜色很简单,涉及在文本之前输出正确的控制字符。
终端颜色
要输出彩色文本,您需要echo控制字符以获得所需的颜色,然后输出文本,然后(为了整洁)将输出重置为默认值。下表列出了代码
颜色 | 前景 | 背景 |
Default | ESC[39m | ESC[49m |
Black | ESC[30m | ESC[40m |
Dark red | ESC[31m | ESC[41m |
Dark green | ESC[32m | ESC[42m |
Dark yellow (Orange-ish) | ESC[33m | ESC[43m |
Dark blue | ESC[34m | ESC[44m |
Dark magenta | ESC[35m | ESC[45m |
Dark cyan | ESC[36m | ESC[46m |
Light gray | ESC[37m | ESC[47m |
Dark gray | ESC[90m | ESC[100m |
Red | ESC[91m | ESC[101m |
Green | ESC[92m | ESC[101m |
Orange | ESC[93m | ESC[103m |
Blue | ESC[94m | ESC[104m |
Magenta | ESC[95m | ESC[105m |
Cyan | ESC[96m | ESC[106m |
White | ESC[97m | ESC[107m |
并且重置代码是ESC [0m其中ESC 是转义码。
前景色字符串的格式为:
"ESC[" + "<0 or 1, meaning normal or bold>;" + "<color code> + "m"
而背景的格式为:
"ESC[" + "<color code>" + "m"
这些代码可以一起输出,以便同时更改前景色和背景色。
使用代码
在输出颜色代码之前,您需要生成ESC序列。这样做可能是最简单的,然后将其存储起来以备后用:
:: Sets up the ESC string for use later in this script
:setESC
for /F "tokens=1,2 delims=#" %%a in ('"prompt #$H#$E# & echo on & for %%b in (1) do rem"') do (
set ESC=%%b
exit /B 0
)
exit /B 0
这将设置一个具有正确顺序的ESC变量
输出红色文本的简单示例
setlocal enabledelayedexpansion
call :setESC
echo !ESC![91mThis is red text!ESC![0m
在白色背景上输出红色文本的示例
setlocal enabledelayedexpansion
call :setESC
echo !ESC![91m!ESC![107mThis is red text on a white background!ESC![0m"
这有点麻烦,所以我创建了一些简单的子例程,它们提供了以更文明的方式输出文本的方法
辅助函数
以下辅助函数允许您执行以下操作
call :WriteLine "This is red text" "Red"
call :WriteLine "This is red text on a white background" "Red" "White"
容易得多。
REM Set to false if you find your environment just doesn't handle colors well
set useColor=true
:: Sets up the ESC string for use later in this script
:setESC
for /F "tokens=1,2 delims=#" %%a in ('"prompt #$H#$E# & echo on & for %%b in (1) do rem"') do (
set ESC=%%b
exit /B 0
)
exit /B 0
:: Sets the currentColor global for the given foreground/background colors
:: currentColor must be output to the terminal before outputing text in
:: order to generate a colored output.
::
:: string foreground color name. Optional if no background provided.
:: Defaults to "White"
:: string background color name. Optional. Defaults to Black.
:setColor
REM If you want to get a little fancy then you can also try
REM - %ESC%[4m - Underline
REM - %ESC%[7m - Inverse
set foreground=%~1
set background=%~2
if "!foreground!"=="" set foreground=White
if /i "!foreground!"=="Default" set foreground=White
if "!background!"=="" set background=Black
if /i "!background!"=="Default" set background=Black
if "!ESC!"=="" call :setESC
REM This requires the setContrastForeground subroutine, which is discussed below
if /i "!foreground!"=="Contrast" (
call :setContrastForeground !background!
set foreground=!contrastForeground!
)
set currentColor=
REM Foreground Colours
if /i "!foreground!"=="Black" set currentColor=!ESC![30m
if /i "!foreground!"=="DarkRed" set currentColor=!ESC![31m
if /i "!foreground!"=="DarkGreen" set currentColor=!ESC![32m
if /i "!foreground!"=="DarkYellow" set currentColor=!ESC![33m
if /i "!foreground!"=="DarkBlue" set currentColor=!ESC![34m
if /i "!foreground!"=="DarkMagenta" set currentColor=!ESC![35m
if /i "!foreground!"=="DarkCyan" set currentColor=!ESC![36m
if /i "!foreground!"=="Gray" set currentColor=!ESC![37m
if /i "!foreground!"=="DarkGray" set currentColor=!ESC![90m
if /i "!foreground!"=="Red" set currentColor=!ESC![91m
if /i "!foreground!"=="Green" set currentColor=!ESC![92m
if /i "!foreground!"=="Yellow" set currentColor=!ESC![93m
if /i "!foreground!"=="Blue" set currentColor=!ESC![94m
if /i "!foreground!"=="Magenta" set currentColor=!ESC![95m
if /i "!foreground!"=="Cyan" set currentColor=!ESC![96m
if /i "!foreground!"=="White" set currentColor=!ESC![97m
if "!currentColor!"=="" set currentColor=!ESC![97m
if /i "!background!"=="Black" set currentColor=!currentColor!!ESC![40m
if /i "!background!"=="DarkRed" set currentColor=!currentColor!!ESC![41m
if /i "!background!"=="DarkGreen" set currentColor=!currentColor!!ESC![42m
if /i "!background!"=="DarkYellow" set currentColor=!currentColor!!ESC![43m
if /i "!background!"=="DarkBlue" set currentColor=!currentColor!!ESC![44m
if /i "!background!"=="DarkMagenta" set currentColor=!currentColor!!ESC![45m
if /i "!background!"=="DarkCyan" set currentColor=!currentColor!!ESC![46m
if /i "!background!"=="Gray" set currentColor=!currentColor!!ESC![47m
if /i "!background!"=="DarkGray" set currentColor=!currentColor!!ESC![100m
if /i "!background!"=="Red" set currentColor=!currentColor!!ESC![101m
if /i "!background!"=="Green" set currentColor=!currentColor!!ESC![102m
if /i "!background!"=="Yellow" set currentColor=!currentColor!!ESC![103m
if /i "!background!"=="Blue" set currentColor=!currentColor!!ESC![104m
if /i "!background!"=="Magenta" set currentColor=!currentColor!!ESC![105m
if /i "!background!"=="Cyan" set currentColor=!currentColor!!ESC![106m
if /i "!background!"=="White" set currentColor=!currentColor!!ESC![107m
exit /B 0
:: Outputs a line, including linefeed, to the terminal using the given foreground / background
:: colors
::
:: string The text to output. Optional if no foreground provided. Default is just a line feed.
:: string Foreground color name. Optional if no background provided. Defaults to "White"
:: string Background color name. Optional. Defaults to "Black"
:WriteLine
SetLocal EnableDelayedExpansion
if "!ESC!"=="" call :setESC
set resetColor=!ESC![0m
set str=%~1
if "!str!"=="" (
echo:
exit /b 0
)
if "!str: =!"=="" (
echo:
exit /b 0
)
if /i "%useColor%"=="true" (
call :setColor %2 %3
echo !currentColor!!str!!resetColor!
) else (
echo !str!
)
exit /b 0
:: Outputs a line without a linefeed to the terminal using the given foreground / background colors
::
:: string The text to output. Optional if no foreground provided. Default is just a line feed.
:: string Foreground color name. Optional if no background provided. Defaults to "White"
:: string Background color name. Optional. Defaults to "Black"
:Write
SetLocal EnableDelayedExpansion
if "!ESC!"=="" call :setESC
set resetColor=!ESC![0m
set str=%~1
if "!str!"=="" exit /b 0
if "!str: =!"=="" exit /b 0
if /i "%useColor%"=="true" (
call :setColor %2 %3
<NUL set /p =!currentColor!!str!!resetColor!
) else (
<NUL set /p =!str!
)
exit /b 0
处理对比度
假设我们已经定义了一组预定义的颜色,并且我们希望使用它们来确保一致性
set color_primary=Blue
set color_mute=Gray
set color_info=Yellow
set color_success=Green
set color_warn=DarkYellow
set color_error=Red
如果我们使用这些作为背景颜色输出文本,我们会得到
call :WriteLine
call :WriteLine "Default color on predefined background"
call :WriteLine
call :WriteLine " Default colored background" "Default"
call :WriteLine " Primary colored background" "Default" %color_primary%
call :WriteLine " Mute colored background" "Default" %color_mute%
call :WriteLine " Info colored background" "Default" %color_info%
call :WriteLine " Success colored background" "Default" %color_success%
call :WriteLine " Warning colored background" "Default" %color_warn%
call :WriteLine " Error colored background" "Default" %color_error%
事情有点模糊,所以让我们再添加一个函数,它将在我们选择的任何背景上提供对比鲜明的前景
:: Sets the name of a color that will providing a contrasting foreground
:: color for the given background color.
::
:: string background color name.
:: on return, contrastForeground will be set
:setContrastForeground
set background=%~1
if "!background!"=="" background=Black
if /i "!background!"=="Black" set contrastForeground=White
if /i "!background!"=="DarkRed" set contrastForeground=White
if /i "!background!"=="DarkGreen" set contrastForeground=White
if /i "!background!"=="DarkYellow" set contrastForeground=White
if /i "!background!"=="DarkBlue" set contrastForeground=White
if /i "!background!"=="DarkMagenta" set contrastForeground=White
if /i "!background!"=="DarkCyan" set contrastForeground=White
if /i "!background!"=="Gray" set contrastForeground=Black
if /i "!background!"=="DarkGray" set contrastForeground=White
if /i "!background!"=="Red" set contrastForeground=White
if /i "!background!"=="Green" set contrastForeground=White
if /i "!background!"=="Yellow" set contrastForeground=Black
if /i "!background!"=="Blue" set contrastForeground=White
if /i "!background!"=="Magenta" set contrastForeground=White
if /i "!background!"=="Cyan" set contrastForeground=Black
if /i "!background!"=="White" set contrastForeground=Black
exit /B 0
我们已经在Write方法中将其连接起来:如果前景色设置为“对比度”,那么前景色将被视为与给定背景具有良好对比度的东西。
使用我们只需做
call :WriteLine " Primary colored background" "Contrast" %color_primary%
call :WriteLine " Mute colored background" "Contrast" %color_mute%
call :WriteLine " Info colored background" "Contrast" %color_info%
call :WriteLine " Success colored background" "Contrast" %color_success%
call :WriteLine " Warning colored background" "Contrast" %color_warn%
call :WriteLine " Error colored background" "Contrast" %color_error%
有趣的点
其中的一个挑战是通过没有换行符的CMD shell输出文本。echo命令默认添加换行符。要在CMD脚本中输出文本而不包含换行符,只需使用
<NUL set /p ="My string goes here"
https://www.codeproject.com/Articles/5329269/How-to-change-text-color-in-a-Windows-terminal