There is another solution that is also based on identifying the error messages sent to STDERR, so it have the same problems described by dbenham in his answer, but it doesn't require to modify the existent Batch files in any way.
The solution uses this trick to show normal lines preceded by a number in one color and error lines preceded by a different color one. This way you may differentiate error lines in the screen, although the colors are not stored in a text file if the output is redirected.
( theBatchFile | findstr /N /A:2A "^" ) 2>&1 1>&3 | findstr /N /A:4E "^"
The problem with this method is that normal and error lines does not appear in its original order, but in separated parts. This happen because each block of lines is processed by different findstr
commands, but this solution may be enough in certain cases.
EDIT: New method added
I made several tests on this solution. Stdout and Stderr lines are not grouped as I thougth at first. Its order depends on the initial delay to start the second findstr
, that causes that initial Stderr lines be delayed, and the fact that both output may be mixed in the screen. If a Batch file show a majority of Stdout lines and a few Stderr lines now and then, then the output preserve the original order.
I wrote a small Batch-JScript hybrid script called ShowErrors.bat
that allows to differentiate Stderr lines in any way you wish:
@if (@CodeSection == @Batch) @then
@echo off
if "%~1" equ "" (
echo ShowErrors.bat command parameters ...
echo/
echo Execute the command and differentiate lines sent to Stderr
goto :EOF
)
%* 2>&1 1>&3 | CScript //nologo //E:JScript "%~F0"
goto :EOF
@end
while ( ! WScript.Stdin.AtEndOfStream ) {
WScript.Stdout.WriteLine("======================================================");
WScript.Stdout.WriteLine("ERROR: "+WScript.Stdin.ReadLine());
}
This is a small Batch file as example of mixed Stdout/Stderr output program:
@echo off
rem Initial delay
ping -n 2 localhost > NUL
for /L %%i in (1,1,4) do echo Starting lines to Stdout
for %%a in ("2 4" "3 6" "4 8") do (
for /F "tokens=1,2" %%i in (%%a) do (
echo %%i lines to Stderr: >&2
for /L %%x in (1,1,%%i) do echo Line %%x to Stderr >&2
ping -n 1 localhost > NUL
echo %%j lines to Stdout:
ping -n 1 localhost > NUL
for /L %%x in (1,1,%%j) do echo Line %%x to Stdout
)
)
This is the output when it is executed in the normal way: test
:
Starting lines to Stdout
Starting lines to Stdout
Starting lines to Stdout
Starting lines to Stdout
2 lines to Stderr:
Line 1 to Stderr
Line 2 to Stderr
4 lines to Stdout:
Line 1 to Stdout
Line 2 to Stdout
Line 3 to Stdout
Line 4 to Stdout
3 lines to Stderr:
Line 1 to Stderr
Line 2 to Stderr
Line 3 to Stderr
6 lines to Stdout:
Line 1 to Stdout
Line 2 to Stdout
Line 3 to Stdout
Line 4 to Stdout
Line 5 to Stdout
Line 6 to Stdout
4 lines to Stderr:
Line 1 to Stderr
Line 2 to Stderr
Line 3 to Stderr
Line 4 to Stderr
8 lines to Stdout:
Line 1 to Stdout
Line 2 to Stdout
Line 3 to Stdout
Line 4 to Stdout
Line 5 to Stdout
Line 6 to Stdout
Line 7 to Stdout
Line 8 to Stdout
This is the output when it is executed via ShowErrors test
:
Starting lines to Stdout
Starting lines to Stdout
Starting lines to Stdout
Starting lines to Stdout
======================================================
ERROR: 2 lines to Stderr:
======================================================
ERROR: Line 1 to Stderr
======================================================
ERROR: Line 2 to Stderr
4 lines to Stdout:
Line 1 to Stdout
Line 2 to Stdout
Line 3 to Stdout
Line 4 to Stdout
======================================================
ERROR: 3 lines to Stderr:
======================================================
ERROR: Line 1 to Stderr
======================================================
ERROR: Line 2 to Stderr
======================================================
ERROR: Line 3 to Stderr
6 lines to Stdout:
Line 1 to Stdout
Line 2 to Stdout
Line 3 to Stdout
Line 4 to Stdout
Line 5 to Stdout
Line 6 to Stdout
======================================================
ERROR: 4 lines to Stderr:
======================================================
ERROR: Line 1 to Stderr
======================================================
ERROR: Line 2 to Stderr
======================================================
ERROR: Line 3 to Stderr
======================================================
ERROR: Line 4 to Stderr
8 lines to Stdout:
Line 1 to Stdout
Line 2 to Stdout
Line 3 to Stdout
Line 4 to Stdout
Line 5 to Stdout
Line 6 to Stdout
Line 7 to Stdout
Line 8 to Stdout