4

In the following .BAT file, test 2 demonstrates the color bug inside a parenthesized block of code, test 3 demonstrates the bug inside a FOR loop, and test 4 shows how the bug can be mitigated by calling a do-nothing subroutine (call :resetANSI). My questions are:

  1. What is the nature of the bug... why do inline color codes fail after the piping to FINDSTR within a parenthesized block of code? Is this bug specific to FINDSTR, or more general? (FINDSTR has some known bugs, but I didn't see this one listed among them.)

  2. Is calling the do-nothing subroutine the best way to mitigate this bug?

Below the code is a screencapture of the display output, that shows the color code fails in tests 2 & 3 in the lines that are supposed to display in magenta.

Thanks in advance to whoever tries to help!

[EDIT 3/26/2020: Because the forum didn't display the Esc character in the colorcode definitions in the .bat code, I edited the .bat code so it will generate the Esc character at runtime.]

@echo off
goto :main

:resetANSI
EXIT /B

:main
setlocal EnableDelayedExpansion
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"

echo %white%Test 1 is NOT in a FOR loop nor within parentheses.
   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 supposed to be magenta, and FINDSTR found and displayed 'success'.%yellow%
echo %cyan%Test 1 completed.

echo %white%Test 2 is within parentheses.
(  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'.%yellow%
)
echo %cyan%Test 2 completed.

echo %white%Test 3 is within a FOR loop.
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'.%yellow%
)
echo %cyan%Test 3 completed.%white%

echo %white%Test 4 is within a FOR loop and includes a call/return after the pipe to FINDSTR.
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 supposed to be magenta, and FINDSTR found and displayed 'success'.%yellow%
)
echo %cyan%Test 4 completed.%white%

exit /B

Screen capture of output of .BAT program

1 Answers1

2

Building on an attempt by user vssher to answer the question (vssher deleted his/her attempt after it was found not to work right) I think I've found the best solution: place the FINDSTR command within nested parentheses. The solution is demonstrated in tests 3 and 4 of the following .bat code, and a screencapture of the display output is shown below the .bat code:

@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...%white%
   echo success | findstr /R success
   echo %magenta%This is magenta and FINDSTR found and displayed 'success' in white.%yellow%
   echo %green%This is green.
echo %cyan%Test 1 completed.

echo:
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...%white%
   echo success | findstr /R success
   echo %magenta%This is supposed to be magenta and FINDSTR found and displayed 'success' in white.
   echo %green%This is supposed to be green.
)
echo %cyan%Test 2 completed.

echo:
echo %white%Test 3 is within parentheses, but color works because FINDSTR is nested within parentheses.
(  echo %yellow%[Test 3] %green%This is Green, %magenta%this is Magenta, and %yellow%this is Yellow.
   echo Next, the string 'success' will be piped to FINDSTR...%white%
   echo success | ( findstr /R success )
   echo %magenta%This is magenta and FINDSTR found and displayed 'success' in white.
   echo %green%This is green.
)
echo %cyan%Test 3 completed.

echo:
echo %white%Test 4 is within parentheses, FINDSTR is nested within parentheses, 
echo and FINDSTR is piped a string that does NOT match what it's searching for.
(  echo %yellow%[Test 4] %green%This is Green, %magenta%this is Magenta, and %yellow%this is Yellow.
   echo Next, the string 'failed' will be piped to FINDSTR...%white%
   echo failed | ( findstr /R success )
   echo %magenta%This is magenta and FINDSTR correctly displayed nothing.
   echo %green%This is green.
)
echo %cyan%Test 4 completed.

Display output of the .bat code

  • Good to see you didn't give up and found a solution. I'd expect the bug is the result of Ansi Escape character usage - there's a number of bugs I've encountered in using Ansi escape codes. At a guess, placing the Findstring command in it's own command block stops the escape code from interfering with it - Given the problem arises only when they share a command block. [May also be worth sharing your findings here](https://stackoverflow.com/questions/8844868/what-are-the-undocumented-features-and-limitations-of-the-windows-findstr-comman) – T3RR0R Apr 09 '20 at 07:57
  • @T3RR0R: Where you wrote "stops the escape code from interfering with findstr" did you mean "stops findstr from interfering with the escape code?" Placing findstr within nested parentheses presumably isolates findstr's buggy side effects to within the nested parentheses. – Dolores Stevens Apr 09 '20 at 13:36
  • I meant it in the order I stated, however that's an untested view of the matter on my part. The way to find which is the culprit is to test with no usage of an escape code prior to findstring, and usage after, and see if the bug persists, same again for testing with usage before but not after. – T3RR0R Apr 09 '20 at 14:49
  • Great question and answer - very well presented and an interesting find. But your rules can be simplified (at least on my enterprise Windows 10 machine). FINDSTR prevents ***all*** console escape sequences from working for subsequent commands within the same command block. It doesn't matter if FINDSTR reads a pipe, redirected input, or a file. The escape sequence failure is not restricted to color codes. A command block is any set of commands within parentheses, and/or commands concatenated via `&`, `&&`, or `||`. – dbenham Apr 09 '20 at 15:20
  • @dbenham: Thanks for the generalization of the problem. Do you know whether enclosing the FINDSTR phrase within parentheses is a general solution, and whether this solution has any unexpected, undesirable side effects? – Dolores Stevens Apr 09 '20 at 16:24
  • I did not do any exhaustive testing, but yes, the nested parentheses seems to be a general solution, and I can't think of any possible undesirable side effects. – dbenham Apr 09 '20 at 16:45