如何在 Windows 命令行中以不同颜色回显

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2048509/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 07:03:12  来源:igfitidea点击:

How to echo with different colors in the Windows command line

windowsbatch-filecommand-linecolors

提问by rui

I know that the color bfcommand sets the colors of the whole command line window but I wanted to to print one single line in a different color.

我知道该color bf命令设置了整个命令行窗口的颜色,但我想用不同的颜色打印一行。

回答by Jens A. Koch

I wanted to to print one single line in a different color.

我想用不同的颜色打印一行。

Use ANSI Escape Sequences.

使用 ANSI 转义序列。

Windows before 10 - no native support for ANSI colors on the console

Windows 10 之前 - 控制台上没有对 ANSI 颜色的本机支持

For Windows version below 10, the Windows command console doesn't support output coloring by default. You could install either Cmder, ConEmu, ANSICONor Mintty(used by default in GitBash and Cygwin) to add coloring support to your Windows command console.

对于低于 10 的 Windows 版本,Windows 命令控制台默认不支持输出着色。您可以安装CmderConEmuANSICONMintty(在 GitBash 和 Cygwin 中默认使用)以向 Windows 命令控制台添加着色支持。

Windows 10 - Command Line Colors

Windows 10 - 命令行颜色

Starting from Windows 10 the Windows console support ANSI Escape Sequences and some colors by default. The feature shipped with the Threshold 2 Update in Nov 2015.

从 Windows 10 开始,Windows 控制台默认支持 ANSI 转义序列和一些颜色。该功能随 2015 年 11 月的 Threshold 2 更新一起提供。

MSDN Documentation

MSDN 文档

Update(05-2019): The ColorToolenables you to change the color scheme of the console. It's part of the Microsoft Terminalproject.

更新(05-2019):ColorTool可让您更改控制台的配色方案。它是 Microsoft Terminal项目的一部分。

Demo

演示

enter image description here

在此处输入图片说明

Batch Command

批处理命令

The win10colors.cmdwas written by Michele Locati:

win10colors.cmd被写了米歇尔Locati

@echo off
cls
echo [101;93m STYLES [0m
echo ^<ESC^>[0m [0mReset[0m
echo ^<ESC^>[1m [1mBold[0m
echo ^<ESC^>[4m [4mUnderline[0m
echo ^<ESC^>[7m [7mInverse[0m
echo.
echo [101;93m NORMAL FOREGROUND COLORS [0m
echo ^<ESC^>[30m [30mBlack[0m (black)
echo ^<ESC^>[31m [31mRed[0m
echo ^<ESC^>[32m [32mGreen[0m
echo ^<ESC^>[33m [33mYellow[0m
echo ^<ESC^>[34m [34mBlue[0m
echo ^<ESC^>[35m [35mMagenta[0m
echo ^<ESC^>[36m [36mCyan[0m
echo ^<ESC^>[37m [37mWhite[0m
echo.
echo [101;93m NORMAL BACKGROUND COLORS [0m
echo ^<ESC^>[40m [40mBlack[0m
echo ^<ESC^>[41m [41mRed[0m
echo ^<ESC^>[42m [42mGreen[0m
echo ^<ESC^>[43m [43mYellow[0m
echo ^<ESC^>[44m [44mBlue[0m
echo ^<ESC^>[45m [45mMagenta[0m
echo ^<ESC^>[46m [46mCyan[0m
echo ^<ESC^>[47m [47mWhite[0m (white)
echo.
echo [101;93m STRONG FOREGROUND COLORS [0m
echo ^<ESC^>[90m [90mWhite[0m
echo ^<ESC^>[91m [91mRed[0m
echo ^<ESC^>[92m [92mGreen[0m
echo ^<ESC^>[93m [93mYellow[0m
echo ^<ESC^>[94m [94mBlue[0m
echo ^<ESC^>[95m [95mMagenta[0m
echo ^<ESC^>[96m [96mCyan[0m
echo ^<ESC^>[97m [97mWhite[0m
echo.
echo [101;93m STRONG BACKGROUND COLORS [0m
echo ^<ESC^>[100m [100mBlack[0m
echo ^<ESC^>[101m [101mRed[0m
echo ^<ESC^>[102m [102mGreen[0m
echo ^<ESC^>[103m [103mYellow[0m
echo ^<ESC^>[104m [104mBlue[0m
echo ^<ESC^>[105m [105mMagenta[0m
echo ^<ESC^>[106m [106mCyan[0m
echo ^<ESC^>[107m [107mWhite[0m
echo.
echo [101;93m COMBINATIONS [0m
echo ^<ESC^>[31m                     [31mred foreground color[0m
echo ^<ESC^>[7m                      [7minverse foreground ^<-^> background[0m
echo ^<ESC^>[7;31m                   [7;31minverse red foreground color[0m
echo ^<ESC^>[7m and nested ^<ESC^>[31m [7mbefore [31mnested[0m
echo ^<ESC^>[31m and nested ^<ESC^>[7m [31mbefore [7mnested[0m

回答by npocmaka

This is a self-compiled bat/.net hybrid(should be saved as .BAT) that can be used on any system that have installed .net framework (it's a rare thing to see an windows without .NET framework even for the oldest XP/2003 installations) . It uses jscript.net compiler to create an exe capable to print strings with different background/foreground color only for the current line.

这是一个自编译的bat/.net 混合体(应该另存为.BAT),可以在任何安装了 .net 框架的系统上使用(即使对于最老的 XP/2003,也很少看到没有 .NET 框架的 windows装置)。它使用 jscript.net 编译器创建一个 exe,该 exe 能够仅为当前行打印具有不同背景/前景色的字符串。

@if (@X)==(@Y) @end /* JScript comment
@echo off
setlocal

for /f "tokens=* delims=" %%v in ('dir /b /s /a:-d  /o:-n "%SystemRoot%\Microsoft.NET\Framework\*jsc.exe"') do (
   set "jsc=%%v"
)

if not exist "%~n0.exe" (
    "%jsc%" /nologo /out:"%~n0.exe" "%~dpsfnx0"
)

%~n0.exe %*

endlocal & exit /b %errorlevel%

*/

import System;

var arguments:String[] = Environment.GetCommandLineArgs();

var newLine = false;
var output = "";
var foregroundColor = Console.ForegroundColor;
var backgroundColor = Console.BackgroundColor;
var evaluate = false;
var currentBackground=Console.BackgroundColor;
var currentForeground=Console.ForegroundColor;


//http://stackoverflow.com/a/24294348/388389
var jsEscapes = {
  'n': '\n',
  'r': '\r',
  't': '\t',
  'f': '\f',
  'v': '\v',
  'b': '\b'
};

function decodeJsEscape(_, hex0, hex1, octal, other) {
  var hex = hex0 || hex1;
  if (hex) { return String.fromCharCode(parseInt(hex, 16)); }
  if (octal) { return String.fromCharCode(parseInt(octal, 8)); }
  return jsEscapes[other] || other;
}

function decodeJsString(s) {
  return s.replace(
      // Matches an escape sequence with UTF-16 in group 1, single byte hex in group 2,
      // octal in group 3, and arbitrary other single-character escapes in group 4.
      /\(?:u([0-9A-Fa-f]{4})|x([0-9A-Fa-f]{2})|([0-3][0-7]{0,2}|[4-7][0-7]?)|(.))/g,
      decodeJsEscape);
}


function printHelp( ) {
   print( arguments[0] + "  -s string [-f foreground] [-b background] [-n] [-e]" );
   print( " " );
   print( " string          String to be printed" );
   print( " foreground      Foreground color - a " );
   print( "                 number between 0 and 15." );
   print( " background      Background color - a " );
   print( "                 number between 0 and 15." );
   print( " -n              Indicates if a new line should" );
   print( "                 be written at the end of the ");
   print( "                 string(by default - no)." );
   print( " -e              Evaluates special character " );
   print( "                 sequences like \n\b\r and etc ");
   print( "" );
   print( "Colors :" );
   for ( var c = 0 ; c < 16 ; c++ ) {

        Console.BackgroundColor = c;
        Console.Write( " " );
        Console.BackgroundColor=currentBackground;
        Console.Write( "-"+c );
        Console.WriteLine( "" );
   }
   Console.BackgroundColor=currentBackground;



}

function errorChecker( e:Error ) {
        if ( e.message == "Input string was not in a correct format." ) {
            print( "the color parameters should be numbers between 0 and 15" );
            Environment.Exit( 1 );
        } else if (e.message == "Index was outside the bounds of the array.") {
            print( "invalid arguments" );
            Environment.Exit( 2 );
        } else {
            print ( "Error Message: " + e.message );
            print ( "Error Code: " + ( e.number & 0xFFFF ) );
            print ( "Error Name: " + e.name );
            Environment.Exit( 666 );
        }
}

function numberChecker( i:Int32 ){
    if( i > 15 || i < 0 ) {
        print("the color parameters should be numbers between 0 and 15");
        Environment.Exit(1);
    }
}


if ( arguments.length == 1 || arguments[1].toLowerCase() == "-help" || arguments[1].toLowerCase() == "-help"   ) {
    printHelp();
    Environment.Exit(0);
}

for (var arg = 1; arg <= arguments.length-1; arg++ ) {
    if ( arguments[arg].toLowerCase() == "-n" ) {
        newLine=true;
    }

    if ( arguments[arg].toLowerCase() == "-e" ) {
        evaluate=true;
    }

    if ( arguments[arg].toLowerCase() == "-s" ) {
        output=arguments[arg+1];
    }


    if ( arguments[arg].toLowerCase() == "-b" ) {

        try {
            backgroundColor=Int32.Parse( arguments[arg+1] );
        } catch(e) {
            errorChecker(e);
        }
    }

    if ( arguments[arg].toLowerCase() == "-f" ) {
        try {
            foregroundColor=Int32.Parse(arguments[arg+1]);
        } catch(e) {
            errorChecker(e);
        }
    }
}

Console.BackgroundColor = backgroundColor ;
Console.ForegroundColor = foregroundColor ;

if ( evaluate ) {
    output=decodeJsString(output);
}

if ( newLine ) {
    Console.WriteLine(output);  
} else {
    Console.Write(output);

}

Console.BackgroundColor = currentBackground;
Console.ForegroundColor = currentForeground;

Here's the help message:

这是帮助消息:

enter image description here

在此处输入图片说明

Example:

示例

coloroutput.bat -s "aa\nbb\n\u0025cc" -b 10 -f 3 -n -e

coloroutput.bat -s "aa\nbb\n\u0025cc" -b 10 -f 3 -n -e

You can also find this script here.

您也可以在此处找到此脚本。

You can also check carlos' color function -> http://www.dostips.com/forum/viewtopic.php?f=3&t=4453

您还可以检查卡洛斯的颜色功能 -> http://www.dostips.com/forum/viewtopic.php?f=3&t=4453

回答by Iain

This isn't a great answer, but if you know the target workstation has Powershell you can do something like this (assuming BAT / CMD script):

这不是一个很好的答案,但是如果您知道目标工作站具有 Powershell,您可以执行以下操作(假设 BAT / CMD 脚本):

CALL:ECHORED "Print me in red!"

:ECHORED
%Windir%\System32\WindowsPowerShell\v1.0\Powershell.exe write-host -foregroundcolor Red %1
goto:eof


Edit: (now simpler!)

编辑:(现在更简单!)

It's an old answer but I figured I'd clarify & simplify a bit

这是一个旧的答案,但我想我会澄清和简化一点

img

图片

PowerShellis now includedin all versionsof Windows since 7. Therefore the syntax for this answer can be shortened to a simpler form:

自 7 以来,PowerShell现在包含在所有版本的 Windows 中。因此,此答案的语法可以缩短为更简单的形式:

  • the pathdoesn't need to be specified since it should be in the environment variable already.
  • unambiguouscommands can be abbreviated. For example you can:
    • use -foreinstead of -foregroundcolor
    • use -backinstead of -backgroundcolor
  • the command can also basically be used 'inline' in place of echo
    (rather than creating a separate batch file as above).
  • 路径并不需要指定,因为它应该是在环境变量了。
  • 明确的命令可以缩写。例如,您可以:
    • 使用-fore代替-foregroundcolor
    • 使用-back代替-backgroundcolor
  • 该命令基本上也可以使用“内联”代替echo
    (而不是像上面那样创建单独的批处理文件)。


Example:

例子:

powershell write-host -fore Cyan This is Cyan text
powershell write-host -back Red This is Red background


More Information:

更多信息:

The complete list of colors and more information is available in the
- PowerShell Documentation for Write-Host

完整的颜色列表和更多信息可在
- PowerShell文档中找到Write-Host

回答by Gringo Suave

Windows 10 - TH2 and above:

Windows 10 - TH2 及更高版本:

(a.k.a. Version 1511, build 10586, release 2015-11-10)

(又名 1511 版,内部版本 10586,发布 2015-11-10)

At Command Prompt:

在命令提示符下:

echo ^[[32m HI ^[[0m

Using the actual keys:?? echo Ctrl+[[32m HICtrl+[[0mEnter

使用实际的键:?? 回声Ctrl+ [[32m HICtrl+[[0mEnter

You should see a green "HI" below it.

您应该会在其下方看到一个绿色的“HI”。

Code numbers can be found here:

代码编号可以在这里找到:

Notepad:

记事本:

To save this into notepad, you can type ESC into it using: Alt+027with the numpad, then the [32mpart. Another trick when I was on a laptop, redirect the line above into a file to get started, then cut and paste:

要将其保存到记事本中,您可以使用以下命令在其中输入 ESC:Alt+027和小键盘,然后是[32m零件。当我在笔记本电脑上时,另一个技巧是将上面的行重定向到一个文件中以开始使用,然后剪切和粘贴:

echo echo ^[[32m HI ^[[0m >> batch_file.cmd

回答by Tutankhamen

You can just creates files with the name of the word to print, uses findstr which can print in color, and then erases the file. Try this example:

您可以使用要打印的单词的名称创建文件,使用可以彩色打印的 findstr,然后删除该文件。试试这个例子:

@echo off
SETLOCAL EnableDelayedExpansion
for /F "tokens=1,2 delims=#" %%a in ('"prompt #$H#$E# & echo on & for %%b in (1) do rem"') do (
  set "DEL=%%a"
)

call :ColorText 0a "green"
call :ColorText 0C "red"
call :ColorText 0b "cyan"
echo(
call :ColorText 19 "blue"
call :ColorText 2F "white"
call :ColorText 4e "yellow"

goto :eof

:ColorText
echo off
<nul set /p ".=%DEL%" > "%~2"
findstr /v /a:%1 /R "^$" "%~2" nul
del "%~2" > nul 2>&1
goto :eof

Run color /?to get a list of colors.

运行color /?以获取颜色列表。

回答by Bryan Ash

You could use ANSICONto enable ANSI terminal codes in older versions of Windows. There are 32 and 64 bit versions that I have used in Windows XP and Windows 7.

您可以使用ANSICON在旧版本的 Windows 中启用 ANSI 终端代码。我在 Windows XP 和 Windows 7 中使用了 32 位和 64 位版本。

回答by Nick-n-Chicago

I looked at this because I wanted to introduce some simple text colors to a Win7 Batch file. This is what I came up with. Thanks for your help.

我看这个是因为我想向 Win7 Batch 文件引入一些简单的文本颜色。这就是我想出的。谢谢你的帮助。

@echo off
cls && color 08

rem .... the following line creates a [DEL] [ASCII 8] [Backspace] character to use later
rem .... All this to remove [:]
for /F "tokens=1,2 delims=#" %%a in ('"prompt #$H#$E# & echo on & for %%b in (1) do rem"') do (set "DEL=%%a")

echo.

<nul set /p="("
call :PainText 09 "BLUE is cold"    && <nul set /p=")  ("
call :PainText 02 "GREEN is earth"  && <nul set /p=")  ("
call :PainText F0 "BLACK is night"  && <nul set /p=")"
echo.
<nul set /p="("
call :PainText 04 "RED is blood"    && <nul set /p=")  ("
call :PainText 0e "YELLOW is pee"   && <nul set /p=")  ("
call :PainText 0F "WHITE all colors"&& <nul set /p=")"

goto :end

:PainText
<nul set /p "=%DEL%" > "%~2"
findstr /v /a:%1 /R "+" "%~2" nul
del "%~2" > nul
goto :eof

:end
echo.
pause

回答by Alec Mev

I was annoyed by the lack of proper coloring in cmd too, so I went ahead and created cmdcolor. It's just an stdout proxy, which looks for a limited set of ANSI/VT100 control sequences (in other words, like in bash), i.e. echo \033[31m RED \033[0m DEFAULT | cmdcolor.exe.

我也对 cmd 中缺乏适当的着色感到恼火,所以我继续创建了cmdcolor。它只是一个标准输出代理,它寻找一组有限的 ANSI/VT100 控制序列(换句话说,就像在 bash 中一样),即echo \033[31m RED \033[0m DEFAULT | cmdcolor.exe.

Usage and downloads.

使用和下载

回答by PavDub

There is an accepted answer with more than 250 upvotes already. The reason I am still contributing is that the escapecharacter required for echoing is not accepted by many editors (I am using, e.g., MS Code) and all other solutions require some third-party (non-Windows-default) pieces of software.

已经有 250 多个赞成票的公认答案。我仍然贡献的原因escape是许多编辑器不接受回显所需的字符(我正在使用,例如 MS Code),并且所有其他解决方案都需要一些第三方(非 Windows 默认)软件。

The work-around with using only plain batch commands is using PROMPTinstead of ECHO. The PROMPTcommand accepts the escapecharacter in an any-editor-friendly way as a $Echaracter sequence. (Simply replace the Escin the ASCII Escape codes) with $E.

仅使用普通批处理命令的解决方法是使用PROMPT而不是ECHO. 该PROMPT命令escape以任何编辑器友好的方式接受字符作为$E字符序列。(只需将ASCII 转义码Esc中的替换为)。$E

Here is a demo code:

这是一个演示代码:

@ECHO OFF

    :: Do not pollute environment with the %prompt.bak% variable
    :: ! forgetting ENDLOCAL at the end of the batch leads to prompt corruption
    SETLOCAL

    :: Old prompt settings backup
    SET prompt.bak=%PROMPT%

    :: Entering the "ECHO"-like section

        :: Forcing prompt to display after every command (see below)
        ECHO ON

        :: Setting the prompt using the ANSI Escape sequence(s)
        :: - Always start with $E[1A, otherwise the text would appear on a next line
        :: - Then the decorated text follows
        :: - And it all ends with $E30;40m, which makes the following command invisible
        ::   - assuming default background color of the screen
        @ PROMPT $E[1A$E[30;42mHELLO$E[30;40m

        :: An "empty" command that forces the prompt to display. 
        :: The word "rem" is displayed along with the prompt text but is made invisible
        rem

        :: Just another text to display
        @ PROMPT $E[1A$E[33;41mWORLD$E[30;40m
        rem

        :: Leaving the "ECHO"-like section
        @ECHO OFF

    :: Or a more readable version utilizing the cursor manipulation ASCII ESC sequences

        :: the initial sequence
        PROMPT $E[1A
        :: formating commands
        PROMPT %PROMPT%$E[32;44m
        :: the text
        PROMPT %PROMPT%This is an "ECHO"ed text...
        :: new line; 2000 is to move to the left "a lot"
        PROMPT %PROMPT%$E[1B$E[2000D
        :: formating commands fro the next line
        PROMPT %PROMPT%$E[33;47m
        :: the text (new line)
        PROMPT %PROMPT%...spreading over two lines
        :: the closing sequence
        PROMPT %PROMPT%$E[30;40m

        :: Looks like this without the intermediate comments:
        :: PROMPT $E[1A
        :: PROMPT %PROMPT%$E[32;44m
        :: PROMPT %PROMPT%This is an "ECHO"ed text...
        :: PROMPT %PROMPT%$E[1B$E[2000D
        :: PROMPT %PROMPT%$E[33;47m
        :: PROMPT %PROMPT%...spreading over two lines
        :: PROMPT %PROMPT%$E[30;40m

        :: show it all at once!
        ECHO ON
        rem
        @ECHO OFF

    :: End of "ECHO"-ing

    :: Setting prompt back to its original value
    :: - We prepend the settings with $E[37;40m in case
    ::   the original prompt settings do not specify color
    ::   (as they don't by default).
    :: - If they do, the $E[37;40m will become overridden, anyway.
    :: ! It is important to write this command 
    ::   as it is with `ENDLOCAL` and in the `&` form.
    ENDLOCAL & PROMPT $E[37;40m%prompt.bak%

EXIT /B 0

NOTE: The only drawback is that this technique collides with user cmd color settings (colorcommand or settings) if not known explicitly.

注意:唯一的缺点是,color如果不明确知道,此技术会与用户 cmd 颜色设置(命令或设置)发生冲突。

-- Hope this helps as thi is the only solution acceptable for me for the reasons mentioned at the beginning. --

- 希望这会有所帮助,因为出于开头提到的原因,这是我唯一可以接受的解决方案。——

EDIT:

编辑:

Based on comments, I am enclosing another snippet inspired by @Jeb. It:

根据评论,我附上了另一个受@Jeb 启发的片段。它:

  • Shows how to obtain and use the "Esc" character runtime (rather than entering it to an editor) (Jeb's solution)
  • Uses "native" ECHOcommand(s)
  • So it does not affect local PROMPTvalue
  • Demonstrates that coloring the ECHOoutput inevitably affect PROMPTcolor so the color must be reset, anyway
  • 演示如何获取和使用“Esc”字符运行时(而不是将其输入到编辑器)(Jeb 的解决方案)
  • 使用“本机”ECHO命令
  • 所以它不会影响本地PROMPT
  • 证明对ECHO输出着色不可避免地会影响PROMPT颜色,因此无论如何都必须重置颜色
@ECHO OFF

    :: ! To observe color effects on prompt below in this script
    ::   run the script from a fresh cmd window with no custom
    ::   prompt settings

    :: Only not to pollute the environment with the %\e% variable (see below)
    :: Not needed because of the `PROMPT` variable
    SETLOCAL

        :: Parsing the `escape` character (ASCII 27) to a %\e% variable
        :: Use %\e% in place of `Esc` in the [http://ascii-table.com/ansi-escape-sequences.php]
        FOR /F "delims=#" %%E IN ('"prompt #$E# & FOR %%E IN (1) DO rem"') DO SET "\e=%%E"

        :: Demonstrate that prompt did not get corrupted by the previous FOR
        ECHO ON
        rem : After for
        @ECHO OFF

        :: Some fancy ASCII ESC staff
        ECHO [          ]
        FOR /L %%G IN (1,1,10) DO (
            TIMEOUT /T 1 > NUL
            ECHO %\e%[1A%\e%[%%GC%\e%[31;43m.
            ECHO %\e%[1A%\e%[11C%\e%[37;40m]
        )

        :: ECHO another decorated text
        :: - notice the `%\e%[30C` cursor positioning sequence
        ::   for the sake of the "After ECHO" test below
        ECHO %\e%[1A%\e%[13C%\e%[32;47mHELLO WORLD%\e%[30C

        :: Demonstrate that prompt did not get corrupted by ECHOing
        :: neither does the cursor positioning take effect.
        :: ! But the color settings do.
        ECHO ON
        rem : After ECHO
        @ECHO OFF

    ENDLOCAL

    :: Demonstrate that color settings do not reset
    :: even when out of the SETLOCAL scope
    ECHO ON
    rem : After ENDLOCAL
    @ECHO OFF

    :: Reset the `PROMPT` color
    :: - `PROMPT` itself is untouched so we did not need to backup it.
    :: - Still ECHOING in color apparently collide with user color cmd settings (if any).
    :: ! Resetting `PROMPT` color this way extends the `PROMPT`
    ::   by the initial `$E[37;40m` sequence every time the script runs.
    :: - Better solution then would be to end every (or last) `ECHO` command
    ::   with the `%\e%[37;40m` sequence and avoid setting `PROMPT` altogether.
    ::   which makes this technique preferable to the previous one (before EDIT)
    :: - I am keeping it this way only to be able to
    ::   demonstrate the `ECHO` color effects on the `PROMPT` above.
    PROMPT $E[37;40m%PROMPT%

    ECHO ON
    rem : After PROMPT color reset
    @ECHO OFF

EXIT /B 0

回答by Dolores Stevens

I'm adding an answer to address an issue noted in some comments above: that inline ansi color codes can misbehave when inside a FOR loop (actually, within any parenthesized block of code). The .bat code below demonstrates (1) the use of inline color codes, (2) the color failure that can occur when inline color codes are used in a FOR loop or within a parenthesized block of code, and (3) a solution to the problem.When the .bat code executes, tests 2 and 3 demonstrate the colorcode failure, and test 4 shows no failure because it implements the solution.

我正在添加一个答案来解决上面一些评论中提到的问题:内联 ansi 颜色代码在 FOR 循环内(实际上,在任何带括号的代码块内)时可能会出现错误行为。 下面的 .bat 代码演示了 (1) 内联颜色代码的使用,(2) 在 FOR 循环或括号内的代码块中使用内联颜色代码时可能发生的颜色失败,以及 (3) 解决方案问题。当 .bat 代码执行时,测试 2 和 3 显示颜色代码失败,测试 4 显示没有失败,因为它实现了解决方案。

[EDIT 2020-04-07: I found another solution that's presumably more efficient than calling a subroutine. Enclose the FINDSTR phrase in parentheses, as in the following line:

[编辑 2020-04-07:我找到了另一种可能比调用子程序更有效的解决方案。将 FINDSTR 短语括在括号中,如下行所示:

   echo success | (findstr /R success)

ENDEDIT]

结束编辑]

Note: In my (limited) experience, the color code problem manifests only after input is piped to FINDSTR inside the block of code. That's how the following .bat reproduces the problem. It's possible the color code problem is more general than after piping to FINDSTR. If someone can explain the nature of the problem, and if there's a better way to solve it, I'd appreciate it.

注意:根据我的(有限)经验,颜色代码问题仅在输入通过管道传输到代码块内的 FINDSTR 后才会出现。这就是以下 .bat 重现问题的方式。 颜色代码问题可能比管道到 FINDSTR 后更普遍。如果有人可以解释问题的性质,并且有更好的方法来解决它,我将不胜感激。

@goto :main
:resetANSI
EXIT /B
rem  The resetANSI subroutine is used to fix the colorcode
rem  bug, even though it appears to do nothing.

:main
@echo off
setlocal EnableDelayedExpansion

rem  Define some useful colorcode vars:
for /F "delims=#" %%E in ('"prompt #$E# & for %%E in (1) do rem"') do set "ESCchar=%%E"
set "green=%ESCchar%[92m"
set "yellow=%ESCchar%[93m"
set "magenta=%ESCchar%[95m"
set "cyan=%ESCchar%[96m"
set "white=%ESCchar%[97m"
set "black=%ESCchar%[30m"

echo %white%Test 1 is NOT in a FOR loop nor within parentheses, and color works right.
   echo %yellow%[Test 1] %green%This is Green, %magenta%this is Magenta, and %yellow%this is Yellow.
   echo %Next, the string 'success' will be piped to FINDSTR...
   echo success | findstr /R success
   echo %magenta%This is magenta and FINDSTR found and displayed 'success'.%yellow%
   echo %green%This is green.
echo %cyan%Test 1 completed.

echo %white%Test 2 is within parentheses, and color stops working after the pipe to FINDSTR.
(  echo %yellow%[Test 2] %green%This is Green, %magenta%this is Magenta, and %yellow%this is Yellow.
   echo %Next, the string 'success' will be piped to FINDSTR...
   echo success | findstr /R success
   echo %magenta%This is supposed to be magenta and FINDSTR found and displayed 'success'.
   echo %green%This is supposed to be green.
)
echo %cyan%Test 2 completed.

echo %white%Test 3 is within a FOR loop, and color stops working after the pipe to FINDSTR.
for /L %%G in (3,1,3) do (
   echo %yellow%[Test %%G] %green%This is Green, %magenta%this is Magenta, and %yellow%this is Yellow.
   echo %Next, the string 'success' will be piped to FINDSTR...
   echo success | findstr /R success
   echo %magenta%This is supposed to be magenta and FINDSTR found and displayed 'success'.
   echo %green%This is supposed to be green.
)
echo %cyan%Test 3 completed.

echo %white%Test 4 is in a FOR loop but color works right because subroutine :resetANSI is 
echo called after the pipe to FINDSTR, before the next color code is used.
for /L %%G in (4,1,4) do (
   echo %yellow%[Test %%G] %green%This is Green, %magenta%this is Magenta, and %yellow%this is Yellow.
   echo %Next, the string 'success' will be piped to FINDSTR...
   echo success | findstr /R success
   call :resetANSI
   echo %magenta%This is magenta and FINDSTR found and displayed 'success'.
   echo %green%This is green.
)
echo %cyan%Test 4 completed.%white%

EXIT /B